From dd3306538cfdf545a00ead27135779dbbabf9aed Mon Sep 17 00:00:00 2001 From: Manh Kha Date: Tue, 10 Sep 2024 17:36:28 +0700 Subject: [PATCH] fix ActiveModel::RangeError when using multiple search fields --- lib/ransack/nodes/condition.rb | 48 +++++++++++++++++----------------- spec/ransack/predicate_spec.rb | 9 +++++++ 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/lib/ransack/nodes/condition.rb b/lib/ransack/nodes/condition.rb index af69c037..9621b5b0 100644 --- a/lib/ransack/nodes/condition.rb +++ b/lib/ransack/nodes/condition.rb @@ -284,33 +284,33 @@ def negative? end def arel_predicate - predicate = attributes.map { |attribute| + attributes.map { |attribute| association = attribute.parent - if negative? && attribute.associated_collection? - query = context.build_correlated_subquery(association) - context.remove_association(association) - if self.predicate_name == 'not_null' && self.value - query.where(format_predicate(attribute)) - Arel::Nodes::In.new(context.primary_key, Arel.sql(query.to_sql)) - else - query.where(format_predicate(attribute).not) - Arel::Nodes::NotIn.new(context.primary_key, Arel.sql(query.to_sql)) - end - else - format_predicate(attribute) + predicate = if negative? && attribute.associated_collection? + query = context.build_correlated_subquery(association) + context.remove_association(association) + if self.predicate_name == 'not_null' && self.value + query.where(format_predicate(attribute)) + Arel::Nodes::In.new(context.primary_key, Arel.sql(query.to_sql)) + else + query.where(format_predicate(attribute).not) + Arel::Nodes::NotIn.new(context.primary_key, Arel.sql(query.to_sql)) + end + else + format_predicate(attribute) + end + + if replace_right_node?(predicate) + # Replace right node object to plain integer value in order to avoid + # ActiveModel::RangeError from Arel::Node::Casted. + # The error can be ignored here because RDBMSs accept large numbers + # in condition clauses. + plain_value = predicate.right.value + predicate.right = plain_value end - }.reduce(combinator_method) - if replace_right_node?(predicate) - # Replace right node object to plain integer value in order to avoid - # ActiveModel::RangeError from Arel::Node::Casted. - # The error can be ignored here because RDBMSs accept large numbers - # in condition clauses. - plain_value = predicate.right.value - predicate.right = plain_value - end - - predicate + predicate + }.reduce(combinator_method) end private diff --git a/spec/ransack/predicate_spec.rb b/spec/ransack/predicate_spec.rb index ae0972d9..0d56eb12 100644 --- a/spec/ransack/predicate_spec.rb +++ b/spec/ransack/predicate_spec.rb @@ -42,6 +42,15 @@ module Ransack field = "#{quote_table_name("people")}.#{quote_column_name("salary")}" expect(@s.result.to_sql).to match /#{field} = #{val}/ end + + it 'generates a condition for multiple fields with a huge integer value' do + val = 123456789012345678901 + @s.salary_or_articles_title_eq = val + person_field = "#{quote_table_name("people")}.#{quote_column_name("salary")}" + article_field = "#{quote_table_name("articles")}.#{quote_column_name("title")}" + expect(@s.result.to_sql).to match /#{person_field} = #{val}/ + expect(@s.result.to_sql).to match /#{article_field} = '#{val}'/ + end end describe 'lteq' do