Has Many + non default primary key loads incorrect data.
I assume this is probably also the case for other has_*
relationships, but have not verified.
I have a has_many association from class Foo to
class Bar, where, for this specific relationship,
the primary key on Foo is not id, nor is
the foreign key on Bar id.
class Foo
has_many, :bars, :primary_key => 'a_non_standard_key_name', :foreign_key => 'another_non_standard_key_name'
end
The relationship is one way, I have no need to navigate from
Bar back to Foo, but only call
a_foo.bars.
This works fine when working with a single object, but breaks
down when you want to do eager association preloading to avoid n+1
query problem of loading bars for many foos.
When performing the following you find that
f = Foo.find :all, :include => :Bar
f.bars = [SOMETHING_UNEXPECTED]
The reason is that ActiveRecord creates the preloading query
based on the default primary key of Foo (normally
id).
It queries for
Bar.another_non_standard_key_name
matching Foo.id not
Foo.a_non_standard_key_name
This causes seriously unexpected behaviour, and could easily go
unnoticed since no errors are thrown.
I have found the hook in ActiveRecord where this functionality
should be included and monkey patched for my system, because I need
it now. I can't vouch for it's correctness, but we have many many
specs for our product and none of them have broken because of
this.
I'm running frozen rails 2.2.2
vendor/activerecord/lib/active_record/association_preload.rb,
line 221
Change
primary_key_name = reflection.through_reflection_primary_key_name
to
primary_key_name = reflection.options[:primary_key] || reflection.through_reflection_primary_key_name
Hope this helps someone!
Emma