【问题标题】:ActiveRecord Nested ArraysActiveRecord 嵌套数组
【发布时间】:2020-05-28 19:27:29
【问题描述】:

在将数组用作 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-rails rails-activerecord


    【解决方案1】:

    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
    

    【讨论】:

    • 这很有趣 - 谢谢!,我不确定 ActiveRecord 没有办法构建 WHERE IN 查询的说法。例如Address.where(city: %w[Juneau Albany]) 生成一个IN 查询SELECT "addresses".* FROM "addresses" WHERE "addresses"."city" IN ('Juneau', 'Albany')。括号周围似乎也有一些格式问题(即不将城市/州/国家视为元组)。
    • 是的,但 AR 只会为单个列创建查询,而不是像您尝试创建的查询那样将列列表与值集匹配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多