在循环中,字段=值OR字段的Squeel语法为空

时间:2012-11-01 17:07:29

标签: ruby activerecord squeel

我正在尝试使用循环使用squeel重新创建以下语法:

WHERE season = "value" OR season IS NULL

我能够做到这一点:

where do
  ((season == entry["season"]) | (season == nil)) &
  ((episode == entry["episode"]) | (episode == nil)) &
  ((imdb == entry["imdb"]) | (imdb == nil)) &
  (YEAR(theatrical) == year)

然而,问题是我想在循环中执行 所以我不必为值为空时执行条件(例如,如果imdb没有值I甚至不会使用那条线。)

我有这个:

entry = { "imdb"=>"0364725", "media"=>"DVD", "season"=>"1", ...}
entry.each do |k,v|
    ((k == v) | (k == nil))
  end
end

但它没有将field IS NULL位放在SQL中。

如果Squeel不可能,可以使用ActiveRecord吗?

最终,我正在寻找一种方法来避免在SQL中为这些字段设置条件。如上所述,如果字段为空,我根本不会列出它们,但如果它有值,我需要执行整个field = value OR field IS NULL位。

非常感谢任何帮助。

修改

我现在尝试使用的整个代码是:

matches_found = 
includes(:dvd_director, :dvd_upc, :dvd_series).limit(1).
where do
  (title == title_to_search) &
  entry.each { |k,v| ((k == v) | (k == nil)) }
end

请注意,|之后的所有内容都会被忽略,无论我是否使用__send__(k)

更多信息: 一个非常奇怪的事情是,如果我使用k,v以外的任何东西,它会被忽略。例如:

    entry.each { |k,v| ((k == "bob") | (k == v)) }

“鲍勃”被忽略了!并且值(v)在没有OR语句的情况下被放入SQL中。

2 个答案:

答案 0 :(得分:0)

如果我理解正确,您需要__send__

where do
  (title == title_to_search) & entries.map do |k, v| 
    (__send__(k) == v) | (__send__(k) == nil)
    # or: __send__(k) >> [v, nil]
  end.inject(:&)
end

https://github.com/ernie/squeel/wiki/Tips-and-tricks

答案 1 :(得分:0)

最后,我能想到的唯一解决方案是将nil添加到数组中,以便Squeel正确处理它:

entry.each do |k,v| 
   # we add a nill value so Squeel will do the OR field IS NULL
   entry[k] = [v, nil] if k == "upc" || k == "asin" || k == "freebase" || k == "imdb" 
end

这很难看,但确实有效。现在我确信有更好的方法可以在第3行写出所有or's但这是另一个问题:)