Setting the ID of new database records in Ruby-on-Rails
Switching over from Zend Framework to Ruby-on-Rails presents stumbling blocks. Rails wants to manage your database from A-to-Z. Fair enough.
But. When it comes to inserting data into it via rake db:migrate or rake db:seed (the latter being the correct way of managing your data separately from your schema), you may encounter outright frustration: Rails will not let you set the id of the records!
For example, you write
Singer.find_or_create_by_id(:id => 100, :name => “Donna Summer”, :rating => 2)
but in your database, Dona’s id is just 1, or whatever the next available AUTO INCREMENT number was. I feel love — not.
There are at least two solutions, that hinge on getting around the fact the id is a protected attribute. First one:
singer.find_or_create_by_id (:id => 100, :name => “Dona Summers”, :rating => 2) {|record| record.id = 100}
or you can make use of the attributes= method of ActiveRecord::Base in the following way:
Singer.attributes=({ :name => ‘Donna Summer’, :rating => 2}, false)
The false passed as third parameter means “do not protect the protected attributes”. The RoR API documentation puts it this way:
attributes=(new_attributes, guard_protected_attributes = true)
Allows you to set all the attributes at once by passing in a hash with keys matching the attribute names (which again matches the column names).
If guard_protected_attributes is true (the default), then sensitive attributes can be protected from this form of mass-assignment by using the attr_protected macro. Or you can alternatively specify which attributes can be accessed with the attr_accessible macro. Then all the attributes not included in that won‘t be allowed to be mass-assigned.
Look it up on http://api.rubyonrails.org/
