aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorMatt Jones <al2o3cr@gmail.com>2008-12-02 16:21:21 -0500
committerPratik Naik <pratiknaik@gmail.com>2008-12-18 19:19:36 +0000
commita9422cc1db9501a80ecf2c25a5d3b0c4f4f32763 (patch)
tree27f933f524f033434448fd953cf24285c36d007f /activerecord
parent8326b95169ae6af3b81f5596107fef9db4bcbbb0 (diff)
downloadrails-a9422cc1db9501a80ecf2c25a5d3b0c4f4f32763.tar.gz
rails-a9422cc1db9501a80ecf2c25a5d3b0c4f4f32763.tar.bz2
rails-a9422cc1db9501a80ecf2c25a5d3b0c4f4f32763.zip
Fix preloading of has_one :through associations on belongs_to [#1507 state:resolved]
Signed-off-by: Frederick Cheung <frederick.cheung@gmail.com>
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/association_preload.rb15
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb6
-rw-r--r--activerecord/test/cases/associations/has_one_through_associations_test.rb17
-rw-r--r--activerecord/test/fixtures/member_types.yml6
-rw-r--r--activerecord/test/fixtures/members.yml4
-rw-r--r--activerecord/test/models/member.rb1
-rw-r--r--activerecord/test/models/member_detail.rb1
-rw-r--r--activerecord/test/models/member_type.rb3
-rw-r--r--activerecord/test/schema/schema.rb5
9 files changed, 52 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb
index d8aa1051bd..7b1b2d9ad9 100644
--- a/activerecord/lib/active_record/association_preload.rb
+++ b/activerecord/lib/active_record/association_preload.rb
@@ -204,9 +204,18 @@ module ActiveRecord
unless through_records.empty?
source = reflection.source_reflection.name
through_records.first.class.preload_associations(through_records, source)
- through_records.each do |through_record|
- add_preloaded_record_to_collection(id_to_record_map[through_record[through_primary_key].to_s],
- reflection.name, through_record.send(source))
+ if through_reflection.macro == :belongs_to
+ rev_id_to_record_map, rev_ids = construct_id_map(records, through_primary_key)
+ rev_primary_key = through_reflection.klass.primary_key
+ through_records.each do |through_record|
+ add_preloaded_record_to_collection(rev_id_to_record_map[through_record[rev_primary_key].to_s],
+ reflection.name, through_record.send(source))
+ end
+ else
+ through_records.each do |through_record|
+ add_preloaded_record_to_collection(id_to_record_map[through_record[through_primary_key].to_s],
+ reflection.name, through_record.send(source))
+ end
end
end
else
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index 0ff91fbdf8..0fefec1216 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -83,7 +83,11 @@ module ActiveRecord
def to_ary
load_target
- @target.to_ary
+ if @target.is_a?(Array)
+ @target.to_ary
+ else
+ Array(@target)
+ end
end
def reset
diff --git a/activerecord/test/cases/associations/has_one_through_associations_test.rb b/activerecord/test/cases/associations/has_one_through_associations_test.rb
index 7d418de965..f65d76e2ce 100644
--- a/activerecord/test/cases/associations/has_one_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb
@@ -1,5 +1,6 @@
require "cases/helper"
require 'models/club'
+require 'models/member_type'
require 'models/member'
require 'models/membership'
require 'models/sponsor'
@@ -7,7 +8,7 @@ require 'models/organization'
require 'models/member_detail'
class HasOneThroughAssociationsTest < ActiveRecord::TestCase
- fixtures :members, :clubs, :memberships, :sponsors, :organizations
+ fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations
def setup
@member = members(:groucho)
@@ -158,4 +159,18 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
assert @new_organization.members.include?(@member)
end
+ def test_preloading_has_one_through_on_belongs_to
+ assert_not_nil @member.member_type
+ @organization = organizations(:nsa)
+ @member_detail = MemberDetail.new
+ @member.member_detail = @member_detail
+ @member.organization = @organization
+ @member_details = assert_queries(3) do
+ MemberDetail.find(:all, :include => :member_type)
+ end
+ @new_detail = @member_details[0]
+ assert @new_detail.loaded_member_type?
+ assert_not_nil assert_no_queries { @new_detail.member_type }
+ end
+
end
diff --git a/activerecord/test/fixtures/member_types.yml b/activerecord/test/fixtures/member_types.yml
new file mode 100644
index 0000000000..797a57430c
--- /dev/null
+++ b/activerecord/test/fixtures/member_types.yml
@@ -0,0 +1,6 @@
+founding:
+ id: 1
+ name: Founding
+provisional:
+ id: 2
+ name: Provisional
diff --git a/activerecord/test/fixtures/members.yml b/activerecord/test/fixtures/members.yml
index 67a6cc459a..6db945e61d 100644
--- a/activerecord/test/fixtures/members.yml
+++ b/activerecord/test/fixtures/members.yml
@@ -1,4 +1,6 @@
groucho:
name: Groucho Marx
+ member_type_id: 1
some_other_guy:
- name: Englebert Humperdink \ No newline at end of file
+ name: Englebert Humperdink
+ member_type_id: 2
diff --git a/activerecord/test/models/member.rb b/activerecord/test/models/member.rb
index 77a37abb38..255fb569d7 100644
--- a/activerecord/test/models/member.rb
+++ b/activerecord/test/models/member.rb
@@ -8,4 +8,5 @@ class Member < ActiveRecord::Base
has_one :sponsor_club, :through => :sponsor
has_one :member_detail
has_one :organization, :through => :member_detail
+ belongs_to :member_type
end \ No newline at end of file
diff --git a/activerecord/test/models/member_detail.rb b/activerecord/test/models/member_detail.rb
index e731454556..94f59e5794 100644
--- a/activerecord/test/models/member_detail.rb
+++ b/activerecord/test/models/member_detail.rb
@@ -1,4 +1,5 @@
class MemberDetail < ActiveRecord::Base
belongs_to :member
belongs_to :organization
+ has_one :member_type, :through => :member
end
diff --git a/activerecord/test/models/member_type.rb b/activerecord/test/models/member_type.rb
new file mode 100644
index 0000000000..a13561c72a
--- /dev/null
+++ b/activerecord/test/models/member_type.rb
@@ -0,0 +1,3 @@
+class MemberType < ActiveRecord::Base
+ has_many :members
+end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 6217e3bc1c..fbacc692b4 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -195,6 +195,7 @@ ActiveRecord::Schema.define do
create_table :members, :force => true do |t|
t.string :name
+ t.integer :member_type_id
end
create_table :member_details, :force => true do |t|
@@ -210,6 +211,10 @@ ActiveRecord::Schema.define do
t.string :type
end
+ create_table :member_types, :force => true do |t|
+ t.string :name
+ end
+
create_table :references, :force => true do |t|
t.integer :person_id
t.integer :job_id