ransack
ransack copied to clipboard
Or merge operator is ignored
I have a model, Object, with properties:
categories string[]title stringsubtitle stringI'm using a postgres db.
I'm trying to search for matches given a search query q, where q_elements is from q.split and is a list of strings. In this case q_elements = ['a', 'b'].
I want to match objects where either:
- The title matches any element of
q_elementsOR - The subtitle matches any element of
q_elementsOR - Any of the categories matches any element of
q_elements
Below is the ransack line and the generated SQL:
irb(main):030:0> Object.ransack({title_or_subtitle_i_cont_any: q_elements, categories_i_cont_any: q_elements}.try(:merge, m: :or)).r
esult.count
(26.4ms) SELECT COUNT(*) FROM "places" WHERE ((("places"."title" ILIKE '%a%' OR "places"."title" ILIKE '%b%') OR ("places"."subtitle" ILIKE '%a%' OR "places"."subtitle" ILIKE '%b%')) AND (array_to_string(categories, ',') ILIKE '%a%' OR array_to_string(categories, ',') ILIKE '%b%'))
Expected behavior
I think this is all ok, except for the AND operator at ... ILIKE '%b%')) AND (array_to_string ... should be an OR operator. I believe that the m: :or parameter should make this an OR operator.
Actual behavior
The operator at ... ILIKE '%b%')) AND (array_to_string ... is an AND.
I was able to get the desired result with
Place.ransack(
title_or_categories_or_subtitle_i_cont_any: q_elements
).result
I still believe this is a bug, though.