Dirk Bergmann

Developer, panographer. Does consultancy work from own company. Lives in Chiang Mai, Thailand.


Chiang Mai

Hua Hin

Thailand Hotels

ListVote - List. Vote. Learn.

Partnerseek - Find Partners

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:


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:


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:


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

It is therefore necessary to call the initializer (Hotel.new) without the params hash and set the attributes manually:


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