ruby-on-railsrails-activerecordruby-on-rails-7

Possible to remove method in ActiveRecord?


Context: Rails 7.1, only using the DB interaction layers, no web framework, no servers, etc...

I'm sure this is going to ruffle a few feathers, but I keep running into ActiveRecord::DangerousAttributeError regarding .model_name, on a database of vehicle information. Cars have models, and those models have names. "Just change the DB" simply isn't an option. The source DB is externally owned and managed. I literally can not modify it. And I use that DB with externally sourced data from other companies, all of whom use, expect, and understand the concept of "model_name". I physically can modify the data as I read it in, but haven't found a solution where I can make it work.

So I'm wondering if I could instead remove the .model_name method from Rails as my application loads. My application's function is local to my machine and not used elsewhere, and I don't use the Rails method anywhere. So the existence of this method is causing me problems, and removing it from models would not.

Edit: ActiveModel::Naming instance method of .model_name https://api.rubyonrails.org/classes/ActiveModel/Naming.html#method-i-model_name. Absolutely unimportant for me.

Is this doable?


Solution

  • It's an exceptionally bad idea.

    Just because you're not referencing the method directly in your code or aware of it's importance doesn't mean that it's not a core part of the framework.

    The ActiveModel::Naming API may be simple but is used by ActiveModel to interface with everything from forms, I18N, polymorphic routing etc. In short pretty much everything that makes Rails convention over configuration approach work.

    In ActiveRecord the method is used to look up tables based on the class name, derive foreign keys etc.

    While you could potentially explicitly configure everything and avoid some of the resulting errors what you're proposing is not removing the #model_name method - it's essentially monkeypatching over the instance method with the one created from the schema which is many times worse.

    This would open a pandoras box of bugs as the model instance would still respond to #model_name and in the places where it's implicitly used as a string you would be providing Rails with junk instead of something that actually corresponds to the routes or your database tables leading to buggy and unpredicable behavior. This is a lot worse than the places where it will just straight up break because the code expects an instance of ActiveModel::Name.

    ActiveRecord doesn't provide any kind of mechanism to deconflict dangerous method names and doesn't appear to be a very good choice for your application. It's a highly opinionated ORM that assumes you have full control over the database schema and follow it's conventions. If not you're just making life difficult for yourself.

    Use another ORM like Sequel or add an adapter layer between your application and the database like for example replicating the database with less problematic column names.