From 8c71e8b18f0e589b5413a8e6b6d7336a5506c977 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 11 Jan 2011 15:16:09 -0800 Subject: lazily instantiate AR objects in order to avoid NoMethodErrors --- .../lib/active_record/association_preload.rb | 22 ++++++++++++++-------- activerecord/lib/active_record/base.rb | 19 ++++++++++--------- 2 files changed, 24 insertions(+), 17 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index 4c517e3339..68aaff175a 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -137,9 +137,9 @@ module ActiveRecord end end - def set_association_collection_records(id_to_record_map, reflection_name, associated_records, key) + def set_association_collection_records(id_to_parent_map, reflection_name, associated_records, key) associated_records.each do |associated_record| - parent_records = id_to_record_map[associated_record[key].to_s] + parent_records = id_to_parent_map[associated_record[key].to_s] add_preloaded_records_to_collection(parent_records, reflection_name, associated_record) end end @@ -199,7 +199,6 @@ module ActiveRecord right = Arel::Table.new(options[:join_table]).alias('t0') - join_condition = left[reflection.klass.primary_key].eq( right[reflection.association_foreign_key]) @@ -221,17 +220,24 @@ module ActiveRecord custom_conditions = append_conditions(reflection, preload_options) - all_associated_records = associated_records(ids) do |some_ids| + klass = associated_records_proxy.klass + + associated_records(ids) { |some_ids| method = in_or_equal(some_ids) conditions = right[reflection.foreign_key].send(*method) conditions = custom_conditions.inject(conditions) do |ast, cond| ast.and cond end - associated_records_proxy.where(conditions).to_a - end - - set_association_collection_records(id_to_record_map, reflection.name, all_associated_records, 'the_parent_record_id') + relation = associated_records_proxy.where(conditions) + klass.connection.select_all(relation.arel.to_sql, 'SQL', relation.bind_values) + }.map! { |row| + parent_records = id_to_record_map[row['the_parent_record_id'].to_s] + associated_record = klass.instantiate row + add_preloaded_records_to_collection( + parent_records, reflection.name, associated_record) + associated_record + } end def preload_has_one_association(records, reflection, preload_options={}) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 1079094bbf..a5b71ba280 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -880,6 +880,16 @@ module ActiveRecord #:nodoc: record end + + # Finder methods must instantiate through this method to work with the + # single-table inheritance model that makes it possible to create + # objects of different types from the same table. + def instantiate(record) # :nodoc: + model = find_sti_class(record[inheritance_column]).allocate + model.init_with('attributes' => record) + model + end + private def relation #:nodoc: @@ -892,15 +902,6 @@ module ActiveRecord #:nodoc: end end - # Finder methods must instantiate through this method to work with the - # single-table inheritance model that makes it possible to create - # objects of different types from the same table. - def instantiate(record) - model = find_sti_class(record[inheritance_column]).allocate - model.init_with('attributes' => record) - model - end - def find_sti_class(type_name) if type_name.blank? || !columns_hash.include?(inheritance_column) self -- cgit v1.2.3