Rails条件使用NOT NULL
使用导轨3样式我将如何写相反的:
Foo.includes(:bar).where(:bars=>{:id=>nil})
我想findid不是null的地方。 我试过了:
Foo.includes(:bar).where(:bars=>{:id=>!nil}).to_sql
但是,这返回:
=> "SELECT \"foos\".* FROM \"foos\" WHERE (\"bars\".\"id\" = 1)"
这绝对不是我所需要的,几乎就像ARel中的一个bug。
使用Rails 3的规范方法:
Foo.includes(:bar).where("bars.id IS NOT NULL")
ActiveRecord 4.0及以上版本添加where.not
所以你可以这样做:
Foo.includes(:bar).where.not('bars.id' => nil) Foo.includes(:bar).where.not(bars: { id: nil })
我不再推荐使用Squeel ,因为它并不总是有一个全职的维护者,而且它依赖于私人的API导致频繁的中断变化。
这不是ARel中的一个bug,它是你逻辑中的一个bug。
你想在这里是:
Foo.includes(:bar).where(Bar.arel_table[:id].not_eq(nil))
对于Rails4:
所以,你想要的是一个内部连接,所以你真的应该只使用连接谓词:
Foo.joins(:bar) Select * from Foo Inner Join Bars ...
但是,为了logging,如果你想要一个“非空”的条件只是使用不谓词:
Foo.includes(:bar).where.not(bars: {id: nil}) Select * from Foo Left Outer Join Bars on .. WHERE bars.id IS NOT NULL
请注意,这个语法报告了一个弃用(它谈到了一个string的SQL代码片断,但是我认为散列条件在parsing器中被改为string?),所以一定要添加引用到结尾:
Foo.includes(:bar).where.not(bars: {id: nil}).references(:bar)
DEPRECATION警告:它看起来像加载在一个stringSQL片段中引用的表(一个:….)。 例如:
Post.includes(:comments).where("comments.title = 'foo'")
目前,Active Record可识别string中的表,并知道将注释表join查询,而不是在单独的查询中加载注释。 但是,在不编写完整的SQLparsing器的情况下这样做本质上是有缺陷的。 由于我们不想写一个SQLparsing器,我们正在删除这个function。 从现在开始,当你从一个string引用一个表时,你必须明确地告诉Active Record:
Post.includes(:comments).where("comments.title = 'foo'").references(:comments)
使用Rails 4很容易:
Foo.includes(:bar).where.not(bars: {id: nil})
另见: http : //guides.rubyonrails.org/active_record_querying.html#not-conditions
不确定这是有帮助的,但是这在Rails 4中对我有用
Foo.where.not(bar: nil)