From e7c82501361894d463980501cadc8eb2aa3e53f3 Mon Sep 17 00:00:00 2001 From: andrea longhi Date: Fri, 15 Dec 2023 13:21:50 +0100 Subject: [PATCH] Check type before sending `#value` message to predicate The previous implementation was giving for granted that every predicate respond to `#value`, but that doesn't seem to be the case at least when having a `Arel::SelectManager`. by simply inverting the terms of the existing AND check we can fix the issue without introducing unknown side effects. In order to test the change, a new ransacker has been added to the Person model. --- lib/ransack/nodes/condition.rb | 2 +- spec/ransack/adapters/active_record/base_spec.rb | 9 +++++++++ spec/support/schema.rb | 11 +++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/ransack/nodes/condition.rb b/lib/ransack/nodes/condition.rb index af69c037..248638d2 100644 --- a/lib/ransack/nodes/condition.rb +++ b/lib/ransack/nodes/condition.rb @@ -339,7 +339,7 @@ def in_predicate?(predicate) end def casted_array?(predicate) - predicate.value.is_a?(Array) && predicate.is_a?(Arel::Nodes::Casted) + predicate.is_a?(Arel::Nodes::Casted) && predicate.value.is_a?(Array) end def format_values_for(predicate) diff --git a/spec/ransack/adapters/active_record/base_spec.rb b/spec/ransack/adapters/active_record/base_spec.rb index d41cd6d0..ebc54a4c 100644 --- a/spec/ransack/adapters/active_record/base_spec.rb +++ b/spec/ransack/adapters/active_record/base_spec.rb @@ -408,6 +408,15 @@ def self.simple_escaping? expect(s.result.map(&:id)).to eq [3, 2, 1] end + it 'should function correctly with HABTM associations' do + article = Article.first + tag = article.tags.first + s = Person.ransack(article_tags_in: [tag.id]) + + expect(s.result.count).to be 1 + expect(s.result.map(&:id)).to eq [article.person.id] + end + it 'should function correctly when passing an array of strings' do a, b = Person.select(:id).order(:id).limit(2).map { |a| a.id.to_s } diff --git a/spec/support/schema.rb b/spec/support/schema.rb index 555299c4..1000cca0 100644 --- a/spec/support/schema.rb +++ b/spec/support/schema.rb @@ -126,6 +126,17 @@ class Person < ApplicationRecord Arel.sql(query) end + ransacker :article_tags, formatter: proc { |id| + if Tag.exists?(id) + joins(articles: :tags) + .where(tags: { id: id }) + .distinct + .select(:id).arel + end + } do |parent| + parent.table[:id] + end + def self.ransackable_attributes(auth_object = nil) if auth_object == :admin authorizable_ransackable_attributes - ['only_sort']