简体   繁体   中英

ILIKE for multiple columns with Arel and Ransack

I am using Ransack search with a Postgresql DB.

I have an input that I need to search using "ILIKE" (text column) in two different columns.

First I created this ransacker:

ransacker :number do
  Arel.sql("invoice_number::text")
end

That works fine:

Purchase.ransack({number_cont: "123"}).result.to_sql
# => "SELECT \"purchases\".* FROM \"purchases\" WHERE (invoice_number::text ILIKE '%123%')"

However, I want now to search in another column using the same input (so, same ransacker).

I tried doing this:

ransacker :number do |parent|
  Arel::Nodes::InfixOperation.new('OR', parent.table["invoice_number::text"], parent.table["shipping_number::text"])
end

Which returns:

Purchase.ransack({number_cont: "123"}).result.to_sql
# => "SELECT \"purchases\".* FROM \"purchases\" WHERE (\"purchases\".\"invoice_number::text\" OR \"purchases\".\"shipping_number::text\" ILIKE '%123%')"

So as you can see isn't so different from what I need, which is:

"column1::text ILIKE '%123%' OR column2::text ILIKE '%123%'"

Do you know how can I achieve that?

I do following in mysql which works for me

ransacker :invoice_number_or_shipping_number, formatter: proc { |v|
  Purchase.where("invoice_number LIKE ? OR shipping_number LIKE ?", "%#{v}%", "%#{v}%").map(&:id).empty? ?
  "SELECT NULL FROM DUAL WHERE 0 " : Purchase.where("invoice_number LIKE ? OR shipping_number LIKE ?", "%#{v}%", "%#{v}%").map(&:id)
  }, splat_param: true do |parent|
  parent.table[:id]
end

This isn't precisely what you're wanting, but it looks like with the ransack gem, if you combine multiple fields in the query param name it works:

class Purchase < ApplicationRecord
  ransacker :number do
    Arel.sql("invoice_number::text")
  end

  ransacker :shipping do
    Arel.sql("shipping_number::text")
  end
end

puts Purchase.ransack(shipping_or_number_cont: '123').result.to_sql
# => SELECT "purchases".* FROM "purchases"
#  WHERE (shipping_number::text LIKE '%123%' OR invoice_number::text LIKE '%123%')

So if you're able to tweak the param name, this may be easier than trying to do it inside the ransacker block

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM