aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder.rb9
-rw-r--r--activerecord/test/cases/finder_test.rb18
2 files changed, 23 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index a0f6ada3ff..240de3bb69 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -90,16 +90,17 @@ module ActiveRecord
queries.reduce(&:or)
elsif table.aggregated_with?(key)
mapping = table.reflect_on_aggregation(key).mapping
- if mapping.length == 1
+ values = value.nil? ? [nil] : Array.wrap(value)
+ if mapping.length == 1 || values.empty?
column_name, aggr_attr = mapping.first
- values = Array.wrap(value).map do |object|
+ values = values.map do |object|
object.respond_to?(aggr_attr) ? object.public_send(aggr_attr) : object
end
build(table.arel_attribute(column_name), values)
else
- queries = Array.wrap(value).map do |object|
+ queries = values.map do |object|
mapping.map do |field_attr, aggregate_attr|
- build(table.arel_attribute(field_attr), object.send(aggregate_attr))
+ build(table.arel_attribute(field_attr), object.try!(aggregate_attr))
end.reduce(&:and)
end
queries.reduce(&:or)
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 32cf0fb9e7..6af2a43c7f 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -1003,6 +1003,24 @@ class FinderTest < ActiveRecord::TestCase
assert_equal customers(:david), found_customer
end
+ def test_hash_condition_find_nil_with_aggregate_having_one_mapping
+ assert_nil customers(:zaphod).gps_location
+ found_customer = Customer.where(gps_location: nil, name: customers(:zaphod).name).first
+ assert_equal customers(:zaphod), found_customer
+ end
+
+ def test_hash_condition_find_nil_with_aggregate_having_multiple_mappings
+ customers(:david).update(address: nil)
+ assert_nil customers(:david).address_street
+ assert_nil customers(:david).address_city
+ found_customer = Customer.where(address: nil, name: customers(:david).name).first
+ assert_equal customers(:david), found_customer
+ end
+
+ def test_hash_condition_find_empty_array_with_aggregate_having_multiple_mappings
+ assert_nil Customer.where(address: []).first
+ end
+
def test_condition_utc_time_interpolation_with_default_timezone_local
with_env_tz "America/New_York" do
with_timezone_config default: :local do