diff --git a/lib/ransack/nodes/condition.rb b/lib/ransack/nodes/condition.rb index 735bd183..2b07b859 100644 --- a/lib/ransack/nodes/condition.rb +++ b/lib/ransack/nodes/condition.rb @@ -235,11 +235,21 @@ def formatted_values_for_attribute(attr) val = attr.ransacker.formatter.call(val) end val = predicate.format(val) + + # Handle case where formatter for IN/NOT IN predicates returns a string with comma-separated values + if predicate.wants_array && val.is_a?(String) && val.include?("','") + val = val.split("','") + end + if val.is_a?(String) && val.include?('%') val = Arel::Nodes::Quoted.new(val) end val end + + # Flatten the array in case any formatters returned arrays + formatted = formatted.flatten if predicate.wants_array + if predicate.wants_array formatted else diff --git a/spec/ransack/predicate_spec.rb b/spec/ransack/predicate_spec.rb index cf84e200..8377456e 100644 --- a/spec/ransack/predicate_spec.rb +++ b/spec/ransack/predicate_spec.rb @@ -473,6 +473,25 @@ module Ransack expect(@s.result.to_sql).to match /#{field} NOT IN \('a', 'b'\)/ end end + + describe "with 'in' arel predicate and string formatter" do + before do + Ransack.configure do |config| + config.add_predicate 'in_list', + arel_predicate: 'in', + formatter: ->(v) { v&.split(';').join("','") } + end + end + + it 'generates correct IN clause without extra quotes' do + @s.name_in_list = 'test;othertest' + field = "#{quote_table_name("people")}.#{quote_column_name("name")}" + # Should generate: WHERE people.name IN ('test', 'othertest') + # Not: WHERE people.name IN ('test'',''othertest') + expect(@s.result.to_sql).to match /#{field} IN \('test', 'othertest'\)/ + expect(@s.result.to_sql).not_to match /#{field} IN \('test'',''othertest'\)/ + end + end end private