Skip to content

Commit

Permalink
Merge pull request #8403 from senny/3313_after_find_is_triggered_too_…
Browse files Browse the repository at this point in the history
…often

Do not instantiate intermediate AR objects when eager loading.
  • Loading branch information
rafaelfranca committed Dec 4, 2012
2 parents c7e4ee7 + db51704 commit a9dc446
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 2 deletions.
6 changes: 6 additions & 0 deletions 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
Expand Down
6 changes: 4 additions & 2 deletions activerecord/lib/active_record/relation/finder_methods.rb
Expand Up @@ -225,9 +225,11 @@ def construct_limited_ids_condition(relation)
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

Expand Down
6 changes: 6 additions & 0 deletions activerecord/test/cases/associations/eager_test.rb
Expand Up @@ -944,6 +944,12 @@ def test_conditions_on_join_table_with_include_and_limit
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
Expand Down
10 changes: 10 additions & 0 deletions activerecord/test/models/developer.rb
Expand Up @@ -57,6 +57,16 @@ def find_least_recent
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
Expand Down

0 comments on commit a9dc446

Please sign in to comment.