diff --git a/lib/ransack/adapters/active_record/ransack/nodes/condition.rb b/lib/ransack/adapters/active_record/ransack/nodes/condition.rb index f7c0e104..81a78fc6 100644 --- a/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +++ b/lib/ransack/adapters/active_record/ransack/nodes/condition.rb @@ -3,7 +3,7 @@ module Nodes class Condition def arel_predicate - attributes.map { |attribute| + predicate = attributes.map { |attribute| association = attribute.parent if negative? && attribute.associated_collection? query = context.build_correlated_subquery(association) @@ -19,6 +19,17 @@ def arel_predicate format_predicate(attribute) 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 end private @@ -56,6 +67,17 @@ def format_values_for(predicate) end end + def replace_right_node?(predicate) + return false unless predicate.is_a?(Arel::Nodes::Binary) + + arel_node = predicate.right + return false unless arel_node.is_a?(Arel::Nodes::Casted) + + relation, name = arel_node.attribute.values + attribute_type = relation.type_for_attribute(name).type + attribute_type == :integer && arel_node.value.is_a?(Integer) + end + end end end diff --git a/spec/ransack/predicate_spec.rb b/spec/ransack/predicate_spec.rb index 8d2530a0..ae0972d9 100644 --- a/spec/ransack/predicate_spec.rb +++ b/spec/ransack/predicate_spec.rb @@ -35,6 +35,13 @@ module Ransack @s.awesome_eq = nil expect(@s.result.to_sql).not_to match /WHERE/ end + + it 'generates a = condition with a huge integer value' do + val = 123456789012345678901 + @s.salary_eq = val + field = "#{quote_table_name("people")}.#{quote_column_name("salary")}" + expect(@s.result.to_sql).to match /#{field} = #{val}/ + end end describe 'lteq' do @@ -56,6 +63,13 @@ module Ransack @s.salary_lteq = nil expect(@s.result.to_sql).not_to match /WHERE/ end + + it 'generates a <= condition with a huge integer value' do + val = 123456789012345678901 + @s.salary_lteq = val + field = "#{quote_table_name("people")}.#{quote_column_name("salary")}" + expect(@s.result.to_sql).to match /#{field} <= #{val}/ + end end describe 'lt' do @@ -77,6 +91,13 @@ module Ransack @s.salary_lt = nil expect(@s.result.to_sql).not_to match /WHERE/ end + + it 'generates a = condition with a huge integer value' do + val = 123456789012345678901 + @s.salary_lt = val + field = "#{quote_table_name("people")}.#{quote_column_name("salary")}" + expect(@s.result.to_sql).to match /#{field} < #{val}/ + end end describe 'gteq' do @@ -98,6 +119,13 @@ module Ransack @s.salary_gteq = nil expect(@s.result.to_sql).not_to match /WHERE/ end + + it 'generates a >= condition with a huge integer value' do + val = 123456789012345678901 + @s.salary_gteq = val + field = "#{quote_table_name("people")}.#{quote_column_name("salary")}" + expect(@s.result.to_sql).to match /#{field} >= #{val}/ + end end describe 'gt' do @@ -119,6 +147,13 @@ module Ransack @s.salary_gt = nil expect(@s.result.to_sql).not_to match /WHERE/ end + + it 'generates a > condition with a huge integer value' do + val = 123456789012345678901 + @s.salary_gt = val + field = "#{quote_table_name("people")}.#{quote_column_name("salary")}" + expect(@s.result.to_sql).to match /#{field} > #{val}/ + end end describe 'cont' do