Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails belongs_to does not set foreign key id with custom class name

I have my models setup like so:

class User < ActiveRecord::Base
  has_many :posts, :foreign_key => 'author_id'
end

class Post < ActiveRecord::Base
  belongs_to :author, :class_name => 'User'
end

Assuming:

p = Post.first # just any post instance
a = User.first # any user instance

Now this piece of code is acting very weird

p.author = a

After setting the author, the attribute author_id of the post should be set to the id of the user. But this isn't happening.

I tried using models with belongs_to that does not have the class_name parameter and everything works as expected.

Now, one more thing that makes it weirder is that when I change the association to belongs_to :author, :class_name => 'User', :foreign_key => 'author_id', it surprisingly works.

Is this a bug in Rails 3.0.9? Shouldn't the foreign key parameter be unnecessary because as the docs say, its default value is the name of the association appended with _id.

Also note that even without :foreign_key => 'author_id', everything else regarding the association works as expected. (Like fetching the associated model) The only thing not working is the setter method not setting the foreign key.

I know I could just do p.author_id = a.id or just add :foreign_key params to all my associations with class_name, but I prefer the more elegant syntax of p.author = a

like image 974
Heinrich Lee Yu Avatar asked Jul 09 '11 15:07

Heinrich Lee Yu


1 Answers

After reading through lots of Rails code and tracing here's what I found:

This bug exists because of the gem composite_primary_keys which overrode the default rails reflection.rb.

I will have to check how they implemented the primary_key_name and derive_primary_key_name methods.

It was quite a bit of time wasted on this silly bug, but at least I got to learn a lot about ActiveRecord's internals.

like image 65
Heinrich Lee Yu Avatar answered Oct 24 '22 11:10

Heinrich Lee Yu