Вложенные массивы ActiveRecord - PullRequest
2 голосов
/ 28 мая 2020

Существуют ли какие-либо методы / шаблоны для очистки массива массивов при использовании его в качестве 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})))

Работает, но полагается на некое ручное экранирование соединения, которое не кажутся идеальными (и их нелегко обобщить за пределы этой области).

1 Ответ

2 голосов
/ 29 мая 2020

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...