ILIKE 用于 Arel 和 Ransack 的多列

ILIKE for multiple columns with Arel and Ransack

我正在使用 Ransack 搜索和 Postgresql 数据库。

我有一个输入需要在两个不同的列中使用 "ILIKE"(文本列)进行搜索。

首先我创建了这个劫掠者:

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

效果很好:

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

但是,我现在想使用相同的输入在另一列中搜索(所以,同一个掠夺者)。

我试过这样做:

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

哪个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%')"

如您所见,与我需要的并无太大区别,即:

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

你知道我怎样才能做到吗?

我按照 mysql 进行操作,这对我有用

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

这不完全是您想要的,但它看起来像搜查 gem,如果您在查询参数名称中组合多个字段,它会起作用:

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%')

因此,如果您能够调整参数名称,这可能比尝试在 ransacker

中进行调整更容易