From 242fc54f57d8db96eb2d34b1db19b9a61d7412b7 Mon Sep 17 00:00:00 2001
From: Dylan Thacker-Smith <Dylan.Smith@shopify.com>
Date: Thu, 17 Jan 2019 13:33:30 -0500
Subject: activerecord: Use a simpler query condition for aggregates with one
 mapping

---
 .../lib/active_record/relation/predicate_builder.rb | 21 +++++++++++++--------
 activerecord/test/cases/finder_test.rb              |  1 +
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index b59ff912fe..b8d64be343 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -90,16 +90,21 @@ module ActiveRecord
             queries.reduce(&:or)
           elsif table.aggregated_with?(key)
             mapping = table.reflect_on_aggregation(key).mapping
-            queries = Array.wrap(value).map do |object|
-              mapping.map do |field_attr, aggregate_attr|
-                if mapping.size == 1 && !object.respond_to?(aggregate_attr)
-                  build(table.arel_attribute(field_attr), object)
-                else
-                  build(table.arel_attribute(field_attr), object.send(aggregate_attr))
+            if mapping.length == 1
+              mapping.first.yield_self do |field_attr, aggregate_attr|
+                values = Array.wrap(value).map do |object|
+                  object.respond_to?(aggregate_attr) ? object.send(aggregate_attr) : object
                 end
-              end.reduce(&:and)
+                build(table.arel_attribute(field_attr), values)
+              end
+            else
+              queries = Array.wrap(value).map do |object|
+                mapping.map do |field_attr, aggregate_attr|
+                  build(table.arel_attribute(field_attr), object.send(aggregate_attr))
+                end.reduce(&:and)
+              end
+              queries.reduce(&:or)
             end
-            queries.reduce(&:or)
           else
             build(table.arel_attribute(key), value)
           end
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 1c53362bac..6a051c3213 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -947,6 +947,7 @@ class FinderTest < ActiveRecord::TestCase
     assert_kind_of Money, zaphod_balance
     found_customers = Customer.where(balance: [david_balance, zaphod_balance])
     assert_equal [customers(:david), customers(:zaphod)], found_customers.sort_by(&:id)
+    assert_equal Customer.where(balance: [david_balance.amount, zaphod_balance.amount]).to_sql, found_customers.to_sql
   end
 
   def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_aggregate
-- 
cgit v1.2.3


From b278db1d2361656c634c15c94ea981e6d0e327f9 Mon Sep 17 00:00:00 2001
From: Dylan Thacker-Smith <Dylan.Smith@shopify.com>
Date: Thu, 17 Jan 2019 14:16:13 -0500
Subject: Avoid using yield_self to make it easier to backport

---
 activerecord/lib/active_record/relation/predicate_builder.rb | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index b8d64be343..842fb1c54b 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -91,12 +91,11 @@ module ActiveRecord
           elsif table.aggregated_with?(key)
             mapping = table.reflect_on_aggregation(key).mapping
             if mapping.length == 1
-              mapping.first.yield_self do |field_attr, aggregate_attr|
-                values = Array.wrap(value).map do |object|
-                  object.respond_to?(aggregate_attr) ? object.send(aggregate_attr) : object
-                end
-                build(table.arel_attribute(field_attr), values)
+              column_name, aggr_attr = mapping.first
+              values = Array.wrap(value).map do |object|
+                object.respond_to?(aggr_attr) ? object.send(aggr_attr) : object
               end
+              build(table.arel_attribute(column_name), values)
             else
               queries = Array.wrap(value).map do |object|
                 mapping.map do |field_attr, aggregate_attr|
-- 
cgit v1.2.3


From 9905cdc9465c482e193950e2f672c6c6c2e6ded1 Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Thu, 17 Jan 2019 17:00:10 -0500
Subject: Use public_send instead since respond_to? doesn't include
 private/protected methods by default

Co-Authored-By: dylanahsmith <dylan.smith@shopify.com>
---
 activerecord/lib/active_record/relation/predicate_builder.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index 842fb1c54b..a0f6ada3ff 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -93,7 +93,7 @@ module ActiveRecord
             if mapping.length == 1
               column_name, aggr_attr = mapping.first
               values = Array.wrap(value).map do |object|
-                object.respond_to?(aggr_attr) ? object.send(aggr_attr) : object
+                object.respond_to?(aggr_attr) ? object.public_send(aggr_attr) : object
               end
               build(table.arel_attribute(column_name), values)
             else
-- 
cgit v1.2.3