From a9bed985cfd7d1ae93f475542bb878aa939e1c1e Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Mon, 3 Jan 2011 13:38:40 +0000 Subject: 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. --- .../lib/active_record/association_preload.rb | 23 +++++++++++++--------- activerecord/lib/active_record/associations.rb | 1 + .../associations/belongs_to_association.rb | 4 +--- 3 files changed, 16 insertions(+), 12 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index e3aee701a8..5aad2b4558 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -339,22 +339,27 @@ module ActiveRecord 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 diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 35fd1395f7..e7d3e45da2 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1501,6 +1501,7 @@ module ActiveRecord 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 diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index 4cde1c0960..b50ee689cd 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -55,9 +55,7 @@ module ActiveRecord 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 -- cgit v1.2.3