From fb160f6e7d71ece0369c6ba9a011ed060f2dcbcb Mon Sep 17 00:00:00 2001
From: Sean Griffin <sean@thoughtbot.com>
Date: Mon, 22 Dec 2014 15:38:58 -0700
Subject: Don't perform statement caching for `find` when called from a scope

If there is a method defined such as `find_and_do_stuff(id)`, which then
gets called on an association, we will perform statement caching and the
parent ID will not change on subsequent calls.

Fixes #18117
---
 activerecord/lib/active_record/core.rb |  1 +
 activerecord/test/cases/finder_test.rb | 24 +++++++++++++++++++++++-
 activerecord/test/models/tyre.rb       |  8 ++++++++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index c2d5582f02..94d1e07069 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -131,6 +131,7 @@ module ActiveRecord
         return super if block_given? ||
                         primary_key.nil? ||
                         default_scopes.any? ||
+                        current_scope ||
                         columns_hash.include?(inheritance_column) ||
                         ids.first.kind_of?(Array)
 
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 5c98be342f..02dc5d3ad3 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -15,9 +15,11 @@ require 'models/customer'
 require 'models/toy'
 require 'models/matey'
 require 'models/dog'
+require 'models/car'
+require 'models/tyre'
 
 class FinderTest < ActiveRecord::TestCase
-  fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers, :categories, :categorizations
+  fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers, :categories, :categorizations, :cars
 
   def test_find_by_id_with_hash
     assert_raises(ActiveRecord::StatementInvalid) do
@@ -1101,6 +1103,26 @@ class FinderTest < ActiveRecord::TestCase
     end
   end
 
+  test "find on a scope does not perform statement caching" do
+    honda = cars(:honda)
+    zyke = cars(:zyke)
+    tyre = honda.tyres.create!
+    tyre2 = zyke.tyres.create!
+
+    assert_equal tyre, honda.tyres.custom_find(tyre.id)
+    assert_equal tyre2, zyke.tyres.custom_find(tyre2.id)
+  end
+
+  test "find_by on a scope does not perform statement caching" do
+    honda = cars(:honda)
+    zyke = cars(:zyke)
+    tyre = honda.tyres.create!
+    tyre2 = zyke.tyres.create!
+
+    assert_equal tyre, honda.tyres.custom_find_by(id: tyre.id)
+    assert_equal tyre2, zyke.tyres.custom_find_by(id: tyre2.id)
+  end
+
   protected
     def bind(statement, *vars)
       if vars.first.is_a?(Hash)
diff --git a/activerecord/test/models/tyre.rb b/activerecord/test/models/tyre.rb
index bc3444aa7d..e50a21ca68 100644
--- a/activerecord/test/models/tyre.rb
+++ b/activerecord/test/models/tyre.rb
@@ -1,3 +1,11 @@
 class Tyre < ActiveRecord::Base
   belongs_to :car
+
+  def self.custom_find(id)
+    find(id)
+  end
+
+  def self.custom_find_by(*args)
+    find_by(*args)
+  end
 end
-- 
cgit v1.2.3