问题描述:
:导轨找到使用哈希数组</p> <p>我有散列的数组,看起来像这样(使用<code>in</code>条款领域的选择查询通过对)记录
[ {product_id: 7629, group_id: 4}, {product_id: 8202, group_id: 3} ]
我会想要返回的是Items
表中与数组中的一对字段匹配的所有记录。
在SQL它会像这样被检索:
SELECT *
FROM items
WHERE (product_id, group_id) IN (VALUES (7629,4), (8202,3))
,但我有麻烦了轨道.where
条款这样做。这甚至有可能吗?
答
我看到在使用SQL的IN
在这种情况下,没有任何好处。
我会用where
为第一条件和链上的所有其他条件与or
(让Rails的照顾消毒和重型起重):
array = [{ product_id: 7629, group_id: 4 }, { product_id: 8202, group_id: 3 }]
array[1..-1].inject(Model.where(array[0])) { |m, h| m.or(Model.where(h)) }
答
我想不出任何方法来做到这一点,而不诉诸于SQL,即使与Arel。
由于数组不能被引用,我们必须做一些愚蠢的事情,仍然允许它被消毒。这不是一个伟大的解决方案,但它是一个工作。
your_hashes = [ {product_id: 7629, group_id: 4}, {product_id: 8202, group_id: 3} ]
# turn hashes into simple value array
conditions = your_hashes.map { |h| [ h[:product_id], h[:group_id] ] }
=> [[7629, 4], [8202, 3]]
# create a list of "(?)" values that will allow the conditions to be passed in
values = ("(?)," * conditions.length)[0..-2]
=> "(?),(?)"
# use it to look up the values
Model.where("(product_id, group_id) IN (VALUES #{values})", *conditions)
# this is the generated sql:
SELECT "models".* FROM "models" WHERE ((product_id, group_id) IN (VALUES (7629,4),(8202,3)))
不错!这比我提出的要好得多。然而,它正在用'array.shift'修改'array',我认为这不是理想的。 (array.first)){| m,h | m.or(Model.where(h))}''会做同样的事情而不改变数组。 – brainbag
更新了我的答案以解决该问题。 – spickermann