views:

258

answers:

2

ActiveRecord's has_many and belongs_to methods both take a :foreign_key option. If I need to use it to handle a nonstandard FK column name, should I set it for the parent model (has_many), child model (belongs_to), or both, or does it matter?

+1  A: 

You should set the :foreign_key option on both.

Consider the following two models:

class Article < ActiveRecord::Base
  has_many :comments, :foreign_key => "articleID"
end

class Comment < ActiveRecord::Base
  belongs_to :article, :foreign_key => "articleID"
end

Declaring has_many in the Article class allows you to do:

Article.find(12).comments  # Finds all comments with comment.articleID == 12

The belongs_to method call in the Comment model allows for:

Comment.last.article       # Finds article with article.id == comment.articleID

As you can see, in both cases the foreign key is used. If omitted in either location, that particular association proxy will not work properly.

molf
You don't *always* need to set the `:foreign_key` option on both. In your particular example, you do, because you have a legacy column name. However, this issue comes up a lot when you're just renaming an association, i.e., `belongs_to :default_account, :class_name => "Account", :foreign_key => "account_id"`. The corresponding `has_one` in the Account class does not need to specify the foreign key.
Sarah Mei
+1  A: 

belongs_to guesses the foreign key to be the association name plus _id.

has_one guesses the foreign key to be the name of the containing class plus _id.

Usually for a nonstandard key, you only need it in one place.

class Book < ActiveRecord::Base
  # Rails default fk is isbn_id
  belongs_to :isbn, :class_name => "BarCode", :foreign_key => "bar_code_id" 
end

class BarCode < ActiveRecord::Base
  # Rails default fk is bar_code_id, so you don't need to specify it
  has_one :book
end
Sarah Mei