ransack icon indicating copy to clipboard operation
ransack copied to clipboard

Or merge operator is ignored

Open schwartzadev opened this issue 4 years ago • 1 comments

I have a model, Object, with properties:

  • categories string[]
  • title string
  • subtitle string I'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_elements OR
  • The subtitle matches any element of q_elements OR
  • 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.

schwartzadev avatar Oct 08 '21 23:10 schwartzadev

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.

schwartzadev avatar Oct 11 '21 18:10 schwartzadev