public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Fix preloading of has_one :through associations on belongs_to [#1507 
state:resolved]

Signed-off-by: Frederick Cheung <frederick.cheung@gmail.com>
al2o3cr (author)
Tue Dec 02 13:21:21 -0800 2008
lifo (committer)
Thu Dec 18 11:19:36 -0800 2008
commit  a9422cc1db9501a80ecf2c25a5d3b0c4f4f32763
tree    27f933f524f033434448fd953cf24285c36d007f
parent  8326b95169ae6af3b81f5596107fef9db4bcbbb0
...
204
205
206
207
208
209
 
 
 
 
 
 
 
 
 
 
 
 
210
211
212
...
204
205
206
 
 
 
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
0
@@ -204,9 +204,18 @@ module ActiveRecord
0
           unless through_records.empty?
0
             source = reflection.source_reflection.name
0
             through_records.first.class.preload_associations(through_records, source)
0
-            through_records.each do |through_record|
0
-              add_preloaded_record_to_collection(id_to_record_map[through_record[through_primary_key].to_s],
0
-                                                 reflection.name, through_record.send(source))
0
+            if through_reflection.macro == :belongs_to
0
+              rev_id_to_record_map, rev_ids = construct_id_map(records, through_primary_key)
0
+              rev_primary_key = through_reflection.klass.primary_key
0
+              through_records.each do |through_record|
0
+                add_preloaded_record_to_collection(rev_id_to_record_map[through_record[rev_primary_key].to_s],
0
+                                                   reflection.name, through_record.send(source))
0
+              end
0
+            else
0
+              through_records.each do |through_record|
0
+                add_preloaded_record_to_collection(id_to_record_map[through_record[through_primary_key].to_s],
0
+                                                   reflection.name, through_record.send(source))
0
+              end
0
             end
0
           end
0
         else
...
83
84
85
86
 
 
 
 
 
87
88
89
...
83
84
85
 
86
87
88
89
90
91
92
93
0
@@ -83,7 +83,11 @@ module ActiveRecord
0
 
0
       def to_ary
0
         load_target
0
-        @target.to_ary
0
+        if @target.is_a?(Array)
0
+          @target.to_ary
0
+        else
0
+          Array(@target)
0
+        end
0
       end
0
 
0
       def reset
...
1
2
 
3
4
5
...
7
8
9
10
 
11
12
13
...
158
159
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
...
1
2
3
4
5
6
...
8
9
10
 
11
12
13
14
...
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
0
@@ -1,5 +1,6 @@
0
 require "cases/helper"
0
 require 'models/club'
0
+require 'models/member_type'
0
 require 'models/member'
0
 require 'models/membership'
0
 require 'models/sponsor'
0
@@ -7,7 +8,7 @@ require 'models/organization'
0
 require 'models/member_detail'
0
 
0
 class HasOneThroughAssociationsTest < ActiveRecord::TestCase
0
-  fixtures :members, :clubs, :memberships, :sponsors, :organizations
0
+  fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations
0
   
0
   def setup
0
     @member = members(:groucho)
0
@@ -158,4 +159,18 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
0
     assert @new_organization.members.include?(@member)
0
   end
0
 
0
+  def test_preloading_has_one_through_on_belongs_to
0
+    assert_not_nil @member.member_type
0
+    @organization = organizations(:nsa)
0
+    @member_detail = MemberDetail.new
0
+    @member.member_detail = @member_detail
0
+    @member.organization = @organization
0
+    @member_details = assert_queries(3) do
0
+      MemberDetail.find(:all, :include => :member_type)
0
+    end
0
+    @new_detail = @member_details[0]
0
+    assert @new_detail.loaded_member_type?
0
+    assert_not_nil assert_no_queries { @new_detail.member_type }
0
+  end
0
+
0
 end
...
1
2
 
3
4
5
 
 
...
1
2
3
4
 
5
6
7
0
@@ -1,4 +1,6 @@
0
 groucho:
0
   name: Groucho Marx
0
+  member_type_id: 1
0
 some_other_guy:
0
-  name: Englebert Humperdink
0
\ No newline at end of file
0
+  name: Englebert Humperdink
0
+  member_type_id: 2
...
8
9
10
 
11
12
...
8
9
10
11
12
13
0
@@ -8,4 +8,5 @@ class Member < ActiveRecord::Base
0
   has_one :sponsor_club, :through => :sponsor
0
   has_one :member_detail
0
   has_one :organization, :through => :member_detail
0
+  belongs_to :member_type
0
 end
0
\ No newline at end of file
...
1
2
3
 
4
...
1
2
3
4
5
0
@@ -1,4 +1,5 @@
0
 class MemberDetail < ActiveRecord::Base
0
   belongs_to :member
0
   belongs_to :organization
0
+  has_one :member_type, :through => :member
0
 end
...
195
196
197
 
198
199
200
...
210
211
212
 
 
 
 
213
214
215
...
195
196
197
198
199
200
201
...
211
212
213
214
215
216
217
218
219
220
0
@@ -195,6 +195,7 @@ ActiveRecord::Schema.define do
0
 
0
   create_table :members, :force => true do |t|
0
     t.string :name
0
+    t.integer :member_type_id
0
   end
0
 
0
   create_table :member_details, :force => true do |t|
0
@@ -210,6 +211,10 @@ ActiveRecord::Schema.define do
0
     t.string :type
0
   end
0
 
0
+  create_table :member_types, :force => true do |t|
0
+    t.string :name
0
+  end
0
+
0
   create_table :references, :force => true do |t|
0
     t.integer :person_id
0
     t.integer :job_id

Comments