1

我使用 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'))"

这个块的好处是我不必担心变量是否存在,如果只有1个变量,查询将不会使用OR语句等。这很难用常规编写条件而不造成大混乱。

另请注意,此查询的重点是在变量不存在时不使用。 column = NULL进行搜索column = NULL将检索到一堆无用和错误的命中。

然而,Squeel 不再维护,并且在 ActiveRecord 4.1(以及 Rails 4.1 的扩展)方面存在各种失败问题。因此,如果我想使用AR 4.1.1及以上,我唯一的选择就是摆脱我拥有的所有 squeel 查询。

我的问题是,这可能与 AR.where块有关吗?除了不,我似乎找不到其他答案,这是不可能的。

4

2 回答 2

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 注入的风险很小。

同样,这不是一个很好的解决方案,但它是我能想到的最好的解决方案。如果有人有更好的解决方案,我很想听听。

于 2014-05-12T09:15:17.193 回答
-2

假设您在数据库中有表模型和相应的“表”,上述 SQL 中的查询可以通过以下方式在 Rails 中实现 -

Table.where('(imdb = ?) OR (asin = ?) OR (upc = ?)', entry[:imdb], entry[:asin], entry[:upc])
于 2014-05-08T10:16:51.070 回答