From 0d56480c4b547915f99f3581065e52a48bd98ca1 Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Wed, 19 Jul 2017 08:18:43 +0900
Subject: Fix `find_by` with range conditions

`StatementCache` doesn't support range conditions. So we need to through
the args to `FinderMethods#find_by` if range value is passed.
---
 activerecord/lib/active_record/core.rb            | 5 ++---
 activerecord/lib/active_record/statement_cache.rb | 7 ++++++-
 activerecord/test/cases/finder_test.rb            | 4 ++++
 3 files changed, 12 insertions(+), 4 deletions(-)

(limited to 'activerecord')

diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 3ea7b644c2..da0331d9c3 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -166,8 +166,7 @@ module ActiveRecord
 
         id = ids.first
 
-        return super if id.kind_of?(Array) ||
-                         id.is_a?(ActiveRecord::Base)
+        return super if StatementCache.unsupported_value?(id)
 
         key = primary_key
 
@@ -192,7 +191,7 @@ module ActiveRecord
         hash = args.first
 
         return super if !(Hash === hash) || hash.values.any? { |v|
-          v.nil? || Array === v || Hash === v || Relation === v || Base === v
+          StatementCache.unsupported_value?(v)
         }
 
         # We can't cache Post.find_by(author: david) ...yet
diff --git a/activerecord/lib/active_record/statement_cache.rb b/activerecord/lib/active_record/statement_cache.rb
index 1877489e55..ceb7c66766 100644
--- a/activerecord/lib/active_record/statement_cache.rb
+++ b/activerecord/lib/active_record/statement_cache.rb
@@ -106,6 +106,11 @@ module ActiveRecord
 
       klass.find_by_sql(sql, bind_values, preparable: true, &block)
     end
-    alias :call :execute
+
+    def self.unsupported_value?(value)
+      case value
+      when NilClass, Array, Range, Hash, Relation, Base then true
+      end
+    end
   end
 end
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index af21cd529f..b860bb4e18 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -1177,6 +1177,10 @@ class FinderTest < ActiveRecord::TestCase
     assert_equal posts(:eager_other), Post.find_by("id = ?", posts(:eager_other).id)
   end
 
+  test "find_by with range conditions returns the first matching record" do
+    assert_equal posts(:eager_other), Post.find_by(id: posts(:eager_other).id...posts(:misc_by_bob).id)
+  end
+
   test "find_by returns nil if the record is missing" do
     assert_nil Post.find_by("1 = 0")
   end
-- 
cgit v1.2.3