Skip to content
Browse files

When preloading a belongs_to, the target should still be set (to nil)…

… if there is no foreign key present. And the loaded flag should be set on the association proxy. This then allows us to remove the foreign_key_present? check from BelongsToAssociation#find_target. Also added a test for the same thing on polymorphic associations.
  • Loading branch information...
1 parent 99a8d84 commit a9bed985cfd7d1ae93f475542bb878aa939e1c1e @jonleighton jonleighton committed with tenderlove Jan 3, 2011
View
23 activerecord/lib/active_record/association_preload.rb
@@ -339,22 +339,27 @@ def preload_belongs_to_association(records, reflection, preload_options={})
key = record.send(reflection.foreign_key)
key && key.to_s
end
- id_map.delete nil
klasses_and_ids[reflection.klass] = id_map unless id_map.empty?
end
klasses_and_ids.each do |klass, _id_map|
- table = klass.arel_table
primary_key = (reflection.options[:primary_key] || klass.primary_key).to_s
- method = in_or_equal(_id_map.keys)
- conditions = table[primary_key].send(*method)
+ keys = _id_map.keys.compact
- custom_conditions = append_conditions(reflection, preload_options)
- conditions = custom_conditions.inject(conditions) do |ast, cond|
- ast.and cond
- end
+ unless keys.empty?
+ table = klass.arel_table
+ method = in_or_equal(keys)
+ conditions = table[primary_key].send(*method)
- associated_records = klass.unscoped.where(conditions).apply_finder_options(options.slice(:include, :select, :joins, :order)).to_a
+ custom_conditions = append_conditions(reflection, preload_options)
+ conditions = custom_conditions.inject(conditions) do |ast, cond|
+ ast.and cond
+ end
+
+ associated_records = klass.unscoped.where(conditions).apply_finder_options(options.slice(:include, :select, :joins, :order)).to_a
+ else
+ associated_records = []
+ end
set_association_single_records(_id_map, reflection.name, associated_records, primary_key)
end
View
1 activerecord/lib/active_record/associations.rb
@@ -1501,6 +1501,7 @@ def association_accessor_methods(reflection, association_proxy_class)
redefine_method("set_#{reflection.name}_target") do |target|
association = association_proxy_class.new(self, reflection)
association.target = target
+ association.loaded
association_instance_set(reflection.name, association)
end
end
View
4 activerecord/lib/active_record/associations/belongs_to_association.rb
@@ -55,9 +55,7 @@ def replace_keys(record)
end
def find_target
- if foreign_key_present?
- scoped.first.tap { |record| set_inverse_instance(record) }
- end
+ scoped.first.tap { |record| set_inverse_instance(record) }
end
def finder_options
View
9 activerecord/test/cases/associations/eager_test.rb
@@ -212,6 +212,15 @@ def test_finding_with_includes_on_null_belongs_to_association_with_same_include_
end
end
+ def test_finding_with_includes_on_null_belongs_to_polymorphic_association
+ sponsor = sponsors(:moustache_club_sponsor_for_groucho)
+ sponsor.update_attributes!(:sponsorable => nil)
+ sponsor = assert_queries(1) { Sponsor.find(sponsor.id, :include => :sponsorable) }
+ assert_no_queries do
+ assert_equal nil, sponsor.sponsorable
+ end
+ end
+
def test_loading_from_an_association
posts = authors(:david).posts.find(:all, :include => :comments, :order => "posts.id")
assert_equal 2, posts.first.comments.size

0 comments on commit a9bed98

Please sign in to comment.
Something went wrong with that request. Please try again.