diff options
author | Yves Senn <yves.senn@gmail.com> | 2012-12-02 21:24:47 +0100 |
---|---|---|
committer | Yves Senn <yves.senn@garaio.com> | 2012-12-04 11:52:08 +0100 |
commit | db51704bd9458635ad82e6a7de56a9fd56db64d4 (patch) | |
tree | f7e3cf4d528c38145c0e547fd345d2d19823fa6c /activerecord | |
parent | c7e4ee79326d81f78cfa3d958a8fce34fde83a15 (diff) | |
download | rails-db51704bd9458635ad82e6a7de56a9fd56db64d4.tar.gz rails-db51704bd9458635ad82e6a7de56a9fd56db64d4.tar.bz2 rails-db51704bd9458635ad82e6a7de56a9fd56db64d4.zip |
Do not instantiate intermediate AR objects when eager loading.
Closes #3313
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/CHANGELOG.md | 6 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/finder_methods.rb | 6 | ||||
-rw-r--r-- | activerecord/test/cases/associations/eager_test.rb | 6 | ||||
-rw-r--r-- | activerecord/test/models/developer.rb | 10 |
4 files changed, 26 insertions, 2 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 130d0f05d2..aaaf27a211 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,5 +1,11 @@ ## Rails 4.0.0 (unreleased) ## +* Do not instantiate intermediate Active Record objects when eager loading. + These records caused `after_find` to run more than expected. + Fix #3313 + + *Yves Senn* + * Add STI support to init and building associations. Allows you to do BaseClass.new(:type => "SubClass") as well as parent.children.build(:type => "SubClass") or parent.build_child diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index eafe4a54c4..7ddaea1bb0 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -225,9 +225,11 @@ module ActiveRecord orders = relation.order_values.map { |val| val.presence }.compact values = @klass.connection.distinct("#{quoted_table_name}.#{primary_key}", orders) - relation = relation.dup + relation = relation.dup.select(values) + + id_rows = @klass.connection.select_all(relation.arel, 'SQL', relation.bind_values) + ids_array = id_rows.map {|row| row[primary_key]} - ids_array = relation.select(values).collect {|row| row[primary_key]} ids_array.empty? ? raise(ThrowResult) : table[primary_key].in(ids_array) end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 79612c8dee..94437380a4 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -944,6 +944,12 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal 3, Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size end + def test_dont_create_temporary_active_record_instances + Developer.instance_count = 0 + developers = Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a + assert_equal developers.count, Developer.instance_count + end + def test_order_on_join_table_with_include_and_limit assert_equal 5, Developer.all.merge!(:includes => 'projects', :order => 'developers_projects.joined_on DESC', :limit => 5).to_a.size end diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb index 622dd75aeb..1c048bb6b4 100644 --- a/activerecord/test/models/developer.rb +++ b/activerecord/test/models/developer.rb @@ -57,6 +57,16 @@ class Developer < ActiveRecord::Base def log=(message) audit_logs.build :message => message end + + after_find :track_instance_count + cattr_accessor :instance_count + + def track_instance_count + self.class.instance_count ||= 0 + self.class.instance_count += 1 + end + private :track_instance_count + end class AuditLog < ActiveRecord::Base |