Custom Primary Key and Mass Assignment
Say you have an ActiveRecord model with a custom primary key and no field named “id”, a common occurrence when working with legacy data:
hotel.rb
class Hotel < ActiveRecord::Base
set_primary_key :hotel_id(…)
Now you have the pertinent form
<% form_for(@hotel) do |f| %>
<%= f.error_messages %>
<%= f.label 'Hotel ID' %>: <%= f.text_field :hotel_id %>
<%= f.label 'Name' %>: <%= f.text_field :name %>
<%= f.label 'Destination ID' %>: <%= f.text_field :destination_id %>
> ><%= f.submit 'Save' %>
<% end %>and default controller code:
hotels_controller.rb
def create
@hotel = Hotel.new(params[:hotel])respond_to do |format|
if @hotel.save
(…)
However, this won’t work. The mass assignment at
@hotel = Hotel.new(params[:hotel])
can’t be used with a “custom” primary key as this code called by the initializer excludes the primary key:
active_record/base.rb
def attributes_from_column_definition
self.class.columns.inject({}) do |attributes, column|
attributes[column.name] = column.default **unless column.name == self.class.primary_key
** attributes
end
end
It is therefore necessary to call the initializer (Hotel.new) without the params hash and set the attributes manually:
hotel_controller.rb
def create
@hotel = Hotel.new
my_params = params[:hotel]
@hotel.hotel_id = my_params[:hotel_id]
@hotel.name_english = my_params[:name]
@hotel.destination_id = my_params[:destination_id]respond_to do |format|
if @hotel.save(…)
Posted: 28 May 2009