Rails使用哈希数组查找记录

时间:2017-11-18 02:29:09

标签: ruby-on-rails ruby ruby-on-rails-5 arel

(使用in子句选择按字段对查询)

我有一系列哈希,如下所示:

[ {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))

但是我在使用rails .where子句时遇到了麻烦。这甚至可能吗?

2 个答案:

答案 0 :(得分:4)

即使使用Arel,如果不诉诸SQL,我也无法想到任何方法。

由于无法引用数组,我们必须做一些愚蠢的事情才能让它被消毒。这不是一个伟大的解决方案,但它是一个有效的解决方案。

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

答案 1 :(得分:3)

在这种情况下,我认为使用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)) }