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)