ILIKE用于Arel和Ransack的多列

时间:2017-09-18 22:24:55

标签: ruby-on-rails postgresql arel 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

返回:

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

你知道我怎么能实现这个目标吗?

2 个答案:

答案 0 :(得分:0)

我在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

答案 1 :(得分:0)

这并不是你想要的,但是看起来像ransack 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%')

因此,如果您能够调整param名称,这可能比在ransacker块中尝试这样做更容易