Reputation: 38052
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
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