Kevin Sylvestre
Kevin Sylvestre

Reputation: 38052

ActiveRecord Nested Arrays

Do any methods / patterns exist for sanitizing an array of arrays when using it as SQL input?

Looking to implement the following style of query in ActiveRecord:

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

For example:

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})))

Works but relies on some manual connection escaping that doesn't seem ideal (and isn't easily generalized beyond this scope).

Upvotes: 2

Views: 362

Answers (1)

max
max

Reputation: 102222

ActiveRecord does not actually have a built in way to construct a WHERE columns IN values query.

But you can do it with 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

Upvotes: 2

Related Questions