Rails 7.1 raises an error on generating model attributes with dangerous name
A Rails migration is a Ruby file that describes changes to your database schema. Migrations are used to add, remove, or modify database tables and columns. They are also used to create database indexes and constraints.
While adding table attributes,
a developer can easily make a mistake
and
mention column names,
which are keywords in Ruby language.
For example,
if a developer adds a column name as any of the column names as attributes
,
attribute_names
,
changes
,
to_global_id
,
the Rails application should raise an error.
These are known as dangerous_attributes
in Rails.
Before Rails 7.1
Before Rails 7.1, neither a warning nor any error was raised when a developer specified the dangerous attributes as column names in the table. This would create issues in the code if the column names are unchecked, and it would be hard to debug the root cause.
Let's say you have a User
model
and
added a column attribute to it in the database migration.
bin/rails generate model User name:string email:text attributes:jsonb
class CreateUsers < ActiveRecord::Migration[6.0]
def change
create_table :users do |t|
t.string :name
t.string :email
t.jsonb :attributes, default: '{}'
t.timestamps
end
end
end
The migration would work fine without raising any issues
or
concerns.
But when you try to create a User
record in the Rails console,
it will raise the below error:
User.create!(name: "alkesh", email: "[email protected]", attributes: { country: 1 })
=> attributes is defined by Active Record.
Check to make sure that you don't have an attribute
or
method with the same name. (ActiveRecord::DangerousAttributeError)
The developer needs to rework the migration or create a new migration to rename it.
In Rails 7.1
Rails 7.1 raises error on generating model attributes with dangerous name. The feature will raise an error if you specify any dangerous attribute when generating a migration.
bin/rails generate model User name:string email:text attributes:jsonb
=> Could not generate field 'attributes', as it is already defined by Active Record.
The feature saves you time by not proceeding with an invalid attribute and then figuring out the issue.
If you want to check the list of dangerous_attributes
,
you need to execute the command below in the Rails console
or
refer to the method
dangerous_attribute_methods.
def get_dangerous_attributes
(
ActiveRecord::Base.instance_methods +
ActiveRecord::Base.private_instance_methods -
ActiveRecord::Base.superclass.instance_methods -
ActiveRecord::Base.superclass.private_instance_methods +
%i[__id__ dup freeze frozen? hash object_id class clone]
).map { |m| -m.to_s }.to_set.sort
end
get_dangerous_attributes
=> [
"[]",
"[]=",
"__callbacks",
"__callbacks?",
"__id__",
....
....
]
To know more about this feature, please refer to this PR.