Skip to content

Commit

Permalink
Ensure correct record is returned when preloading has_one where more …
Browse files Browse the repository at this point in the history
…than one row exists

Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#73 state:closed]
  • Loading branch information
fcheung authored and NZKoz committed May 6, 2008
1 parent a08004a commit fbebdb0
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 1 deletion.
7 changes: 6 additions & 1 deletion activerecord/lib/active_record/association_preload.rb
Expand Up @@ -65,7 +65,13 @@ def set_association_collection_records(id_to_record_map, reflection_name, associ
end

def set_association_single_records(id_to_record_map, reflection_name, associated_records, key)
seen_keys = {}
associated_records.each do |associated_record|
#this is a has_one or belongs_to: there should only be one record.
#Unfortunately we can't (in portable way) ask the database for 'all records where foo_id in (x,y,z), but please
# only one row per distinct foo_id' so this where we enforce that
next if seen_keys[associated_record[key].to_s]
seen_keys[associated_record[key].to_s] = true
mapped_records = id_to_record_map[associated_record[key].to_s]
mapped_records.each do |mapped_record|
mapped_record.send("set_#{reflection_name}_target", associated_record)
Expand Down Expand Up @@ -122,7 +128,6 @@ def preload_has_one_association(records, reflection, preload_options={})
else
records.each {|record| record.send("set_#{reflection.name}_target", nil)}


set_association_single_records(id_to_record_map, reflection.name, find_associated_records(ids, reflection, preload_options), reflection.primary_key_name)
end
end
Expand Down
4 changes: 4 additions & 0 deletions activerecord/test/cases/associations/eager_test.rb
Expand Up @@ -29,6 +29,10 @@ def test_loading_with_one_association
post = Post.find(:first, :include => :comments, :conditions => "posts.title = 'Welcome to the weblog'")
assert_equal 2, post.comments.size
assert post.comments.include?(comments(:greetings))

posts = Post.find(:all, :include => :last_comment)
post = posts.find { |p| p.id == 1 }
assert_equal Post.find(1).last_comment, post.last_comment
end

def test_loading_conditions_with_or
Expand Down
2 changes: 2 additions & 0 deletions activerecord/test/models/post.rb
Expand Up @@ -9,6 +9,8 @@ def greeting

belongs_to :author_with_posts, :class_name => "Author", :foreign_key => :author_id, :include => :posts

has_one :last_comment, :class_name => 'Comment', :order => 'id desc'

has_many :comments, :order => "body" do
def find_most_recent
find(:first, :order => "id DESC")
Expand Down

0 comments on commit fbebdb0

Please sign in to comment.