diff options
Diffstat (limited to 'activerecord')
6 files changed, 31 insertions, 8 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/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb index 7c561b6f82..9f7086cd07 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -267,7 +267,6 @@ module ActiveRecord FROM pg_class seq, pg_attribute attr, pg_depend dep, - pg_namespace name, pg_constraint cons WHERE seq.oid = dep.objid AND seq.relkind = 'S' 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 124bf65d3a..94437380a4 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -616,8 +616,8 @@ class EagerAssociationTest < ActiveRecord::TestCase general = categories.find { |c| c == categories(:general) } technology = categories.find { |c| c == categories(:technology) } - post1 = general.posts.to_a.find { |p| p == posts(:welcome) } - post2 = technology.posts.to_a.find { |p| p == posts(:welcome) } + post1 = general.posts.to_a.find { |p| p == welcome } + post2 = technology.posts.to_a.find { |p| p == welcome } assert_equal post1.object_id, post2.object_id end @@ -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 @@ -984,10 +990,10 @@ class EagerAssociationTest < ActiveRecord::TestCase post = Post.create!(:title => 'Beaches', :body => "I like beaches!") Reader.create! :person => people(:david), :post => post LazyReader.create! :person => people(:susan), :post => post - + assert_equal 1, post.lazy_readers.to_a.size assert_equal 2, post.lazy_readers_skimmers_or_not.to_a.size - + post_with_readers = Post.includes(:lazy_readers_skimmers_or_not).find(post.id) assert_equal 2, post_with_readers.lazy_readers_skimmers_or_not.to_a.size end diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index b2609f6395..02034c87b4 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -499,7 +499,7 @@ class PersistencesTest < ActiveRecord::TestCase def test_update_column_with_one_changed_and_one_updated t = Topic.order('id').limit(1).first - title, author_name = t.title, t.author_name + author_name = t.author_name t.author_name = 'John' t.update_column(:title, 'super_title') assert_equal 'John', t.author_name 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 |