我使用Squeel完成了这段代码:
.where {
[
entry[:imdb].presence && imdb == entry[:imdb],
entry[:asin].presence && asin == entry[:asin],
entry[:upc].presence && dvd_upc.upc == entry[:upc]
].compact.reduce(:|)
}
如果entry[:variable_name]
存在,这只会为列创建查询,否则会忽略它,非常方便。生成如下查询:
"SELECT * FROM `table` WHERE ((`table`.`imdb` = 3026824 OR `table`.`asin` = 'B00E5PHTR8'))"
关于这个块的好处是我不必担心变量是否存在,如果只有一个变量,查询将不使用OR
语句等。使用常规条件书写起来要困难得多。
另请注意,当变量不存在时,此查询的重点是不使用 column = NULL
。搜索column = NULL
将会检索到一堆无用且错误的匹配。
但是,Squeel不再维护,并且在ActiveRecord 4.1(以及Rails 4.1扩展)方面存在各种各样的失败问题。因此,如果我想使用AR 4.1.1
及以上,我唯一的选择就是摆脱我所有的吱吱声查询。
我的问题是,这可能与AR .where
阻止有关吗?我似乎无法找到答案而不是,这是不可能的。
答案 0 :(得分:1)
最后,我想出了这个:
unique_query = main_query.where(
[
entry[:imdb].presence && "imdb = '#{entry[:imdb]}'",
entry[:asin].presence && "asin = '#{entry[:asin]}'",
entry[:upc].presence && "relation_table.upc = #{entry[:upc]}"
].compact.join(' or ')
)
这不是很好,因为我在查询中有变量,这对SQL注入是开放的,但我无法想出更好的方法。至少查询源是受控制的(它来自应用程序),因此SQL注入的风险很小。
同样,这不是一个很好的解决方案,但它是我能想到的最好的解决方案。如果有人有更好的解决方案,我很乐意听到它。
答案 1 :(得分:-2)
假设您在db中有Table模型和相应的'table',SQL中的上述查询可以通过 -
在rails中实现Table.where('(imdb = ?) OR (asin = ?) OR (upc = ?)', entry[:imdb], entry[:asin], entry[:upc])