This project is archived and is in readonly mode.
Has Many + non default primary key loads incorrect data
Reported by Emma Persky | January 28th, 2009 @ 08:07 PM | in 2.x
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
Comments and changes to this ticket
-
Pratik January 28th, 2009 @ 08:27 PM
- Assigned user set to Frederick Cheung
-
Emma Persky January 29th, 2009 @ 11:16 AM
Ah, just checkout the rails git repo, and it looks like this has already been fixed.
Thanks :)
-
Frederick Cheung May 10th, 2009 @ 03:53 PM
- State changed from new to resolved
-
grosser May 18th, 2010 @ 10:30 AM
Still broken in 2.3.5:
class Product < ActiveRecord::Base ... belongs_to :shop, :primary_key => :user_id, :foreign_key => :user_id end
Product.first(:include=>:shop)
SELECT * FROM
products LIMIT 1 SELECT * FROMshops
WHERE (shops
.id
= 13008)but should be:
SELECT * FROM
products LIMIT 1 SELECT * FROMshops
WHERE (shops
.user_id
= 13008)
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>