public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Ensure correct record is returned when preloading has_one where more than one 
row exists

Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#73 state:closed]
fcheung (author)
Thu May 01 16:00:42 -0700 2008
NZKoz (committer)
Tue May 06 02:08:52 -0700 2008
commit  fbebdb0c091c37b0bc75ab774d187d8bc8795bd2
tree    ce0267cb79b2f960b71a336598b14ee828b55460
parent  a08004a9a7d4c93c39f9693f6406ecb70d6a38c0
...
65
66
67
 
68
 
 
 
 
 
69
70
71
...
122
123
124
125
126
127
128
...
65
66
67
68
69
70
71
72
73
74
75
76
77
...
128
129
130
 
131
132
133
0
@@ -65,7 +65,13 @@ module ActiveRecord
0
       end
0
 
0
       def set_association_single_records(id_to_record_map, reflection_name, associated_records, key)
0
+        seen_keys = {}
0
         associated_records.each do |associated_record|
0
+          #this is a has_one or belongs_to: there should only be one record.
0
+          #Unfortunately we can't (in portable way) ask the database for 'all records where foo_id in (x,y,z), but please
0
+          # only one row per distinct foo_id' so this where we enforce that
0
+          next if seen_keys[associated_record[key].to_s]
0
+          seen_keys[associated_record[key].to_s] = true
0
           mapped_records = id_to_record_map[associated_record[key].to_s]
0
           mapped_records.each do |mapped_record|
0
             mapped_record.send("set_#{reflection_name}_target", associated_record)
0
@@ -122,7 +128,6 @@ module ActiveRecord
0
         else
0
           records.each {|record| record.send("set_#{reflection.name}_target", nil)}
0
 
0
-
0
           set_association_single_records(id_to_record_map, reflection.name, find_associated_records(ids, reflection, preload_options), reflection.primary_key_name)
0
         end
0
       end
...
29
30
31
 
 
 
 
32
33
34
...
29
30
31
32
33
34
35
36
37
38
0
@@ -29,6 +29,10 @@ class EagerAssociationTest < ActiveRecord::TestCase
0
     post = Post.find(:first, :include => :comments, :conditions => "posts.title = 'Welcome to the weblog'")
0
     assert_equal 2, post.comments.size
0
     assert post.comments.include?(comments(:greetings))
0
+
0
+    posts = Post.find(:all, :include => :last_comment)
0
+    post = posts.find { |p| p.id == 1 }
0
+    assert_equal Post.find(1).last_comment, post.last_comment
0
   end
0
 
0
   def test_loading_conditions_with_or
...
9
10
11
 
 
12
13
14
...
9
10
11
12
13
14
15
16
0
@@ -9,6 +9,8 @@ class Post < ActiveRecord::Base
0
 
0
   belongs_to :author_with_posts, :class_name => "Author", :foreign_key => :author_id, :include => :posts
0
 
0
+  has_one :last_comment, :class_name => 'Comment', :order => 'id desc'
0
+
0
   has_many   :comments, :order => "body" do
0
     def find_most_recent
0
       find(:first, :order => "id DESC")

Comments