首页 > 解决方案 > ActiveRecord 嵌套数组

问题描述

在将数组用作 SQL 输入时,是否存在任何用于清理数组数组的方法/模式?

希望在 ActiveRecord 中实现以下查询样式:

SELECT *
FROM "addresses"
WHERE ("addresses"."city", "addresses"."state", "addresses"."country") IN (
  ('Juneau', 'AK', 'US'), 
  ('Albany', 'NY', 'US'),
  ...
)

例如:

searches = [
  ['Juneau', 'AK', 'US'],
  ['Albany', 'NY', 'US'],
]

searches_sql = searches.map do |search| 
  "(#{search.map { |query| Address.connection.quote(query) }.join(', ')})"
end.join(', ')
Address.where(%(("addresses"."city", "addresses"."state", "addresses"."country") IN (#{searches_sql})))

有效,但依赖于一些看起来并不理想的手动连接转义(并且在此范围之外不容易泛化)。

标签: ruby-on-railsrails-activerecord

解决方案


ActiveRecord 实际上并没有内置的方式来构造WHERE columns IN values查询。

但是你可以用 Arel 做到这一点:

class Address
  def self.search(sets)
    where(
      Arel::Nodes::In.new(
        [:city, :state, :country].map { |c| arel_table[c] },
        sets.map do |set|
          Arel::Nodes::Grouping.new(
            set.map {|value| Arel::Nodes.build_quoted(value)}
          )
        end
      )
    )
  end
end

推荐阅读