我从POST请求中收到一组参数,它们如下所示:
Parameters:
{"search"=>
{ "minor"=>["1", "1"], "major"=>["1", "2"], "proximity_uuid"=>
["12345453453", "12345453453"]
}
}
这意味着我要求两件物品:
一个有params:
minor:1
专业:1
prox_uuid: 12345453453
和第二个:
minor:1
专业:2
prox_uuid: 12345453453
正如您可能猜到的,我需要从DB中选择与这些条件完全匹配的项目。
我使用以下查询:
selectbeacon = Beacon.includes(:ads, :venue).where('minor IN (?)
and major IN (?) and proximity_uuid IN (?)', params[:search][:minor],
params[:search][:major], params[:search][:proximity_uuid])
然而,问题是它选择了至少匹配一个条件的所有记录,但我需要匹配所有三个。
作为最终结果,我正在生成复杂的JSON响应。
我该如何调整查询?
提前谢谢你,
罗马
答案 0 :(得分:1)
set1 = [:minor, :major, :proximity_uuid].map { |i| params[:search][i][0] }
set2 = [:minor, :major, :proximity_uuid].map { |i| params[:search][i][-1] }
Beacon.includes(:ads, :venue)
.where("(minor = ? and major = ? and proximity_uuid = ?) or
(minor = ? and major = ? and proximity_uuid = ?)",
*set1, *set2
)
在我的控制台玩了一段时间之后,我找到了另一种写上述查询的方法:
Beacon.includes(:ads, :venue)
.where("(minor, major, proximity_uuid)
IN (values(?,?,?),(?,?,?))", *set1, *set2
)
在控制台中测试:
Loading development environment (Rails 4.1.1)
[1] pry(main)> Pet.all
Pet Load (0.7ms) SELECT "pets".* FROM "pets"
=> [#<Pet id: 6, animals: 1, created_at: "2015-02-21 10:40:19", updated_at: "2015-02-21 10:40:19", name: "Tilly">,
#<Pet id: 7, animals: 0, created_at: "2015-02-21 10:40:31", updated_at: "2015-02-21 10:40:54", name: "Xav">,
#<Pet id: 5, animals: 1, created_at: "2015-02-19 18:27:28", updated_at: "2015-02-21 10:41:06", name: "Mua">]
[2] pry(main)> Pet.where("(id, animals) IN (values(?,?),(?,?))",6,1,5,1)
Pet Load (1.3ms) SELECT "pets".* FROM "pets" WHERE ((id, animals) IN (values(6,1),(5,1)))
=> [#<Pet id: 6, animals: 1, created_at: "2015-02-21 10:40:19", updated_at: "2015-02-21 10:40:19", name: "Tilly">,
#<Pet id: 5, animals: 1, created_at: "2015-02-19 18:27:28", updated_at: "2015-02-21 10:41:06", name: "Mua">]
答案 1 :(得分:0)
在玩了一段时间后,在我的朋友的帮助下,这是解决方案:
POST参数应如下所示:
search[0][minor] = 1
search[0][major] = 1
search[0][proximity_uuid] = 1111
...
和查询应该是:
result = params["search"].inject([]) { | result, (key, item) | result | Beacon.includes(:ads, :venue).where('minor=? and major=? and proximity_uuid=?', item["minor"], item["major"], item["proximity_uuid"]) }