Defining primary and foreign keys in Active Record associations
In one of my Rails 4 projects, I found that it was easier to use the source database’s primary and foreign keys. The source database would drop and reuse keys without leaving a history of changes. Fortunately, Active Record makes it easy to change the keys used by the associations.
has_many and has_one
class Customer < ActiveRecord::Base
has_many :accounts, primary_key: "customer_number",
foreign_key: "customer_number"
has_many :account_sales, through: :accounts
has_one :main_hq, primary_key: "customer_number",
foreign_key: "customer_number", class_name: "Office"
end
The Customer table’s primary key is customer_number. The associated table, accounts
, has a column called customer_number that serves as the foreign key.
The same logic goes for the main_hq
association. The option class_name
is used because the model cannot be derived from the association’s name.
belongs_to
class Account < ActiveRecord::Base
belongs_to :customer, primary_key: "customer_number", foreign_key: "customer_number"
has_many :account_sales
On the Account
side, the primary_key
refers to the Customer table’s primary key, and the foreign_key
is the local attribute or column.
Indexing
Index your tables on the primary and foreign keys.
class AddIndexToCustomers < ActiveRecord::Migration
def change
add_index :customers, :customer_number
end
end
class AddIndexToAccounts < ActiveRecord::Migration
def change
add_index :accounts, :customer_number
end
end