使用rails 3样式我怎么写相反的:
Foo.includes(:bar).where(:bars=>{:id=>nil})
我想找到id不是零的地方。 我试过了:
Foo.includes(:bar).where(:bars=>{:id=>!nil}).to_sql
但那回归:
=> "SELECT \"foos\".* FROM \"foos\" WHERE (\"bars\".\"id\" = 1)"
这绝对不是我需要的,而且几乎看起来像是ARel中的一个错误。
#1楼
对于Rails4:
所以,你想要的是一个内连接,所以你真的应该只使用连接谓词:
Foo.joins(:bar)
Select * from Foo Inner Join Bars ...
但是,对于记录,如果你想要一个“NOT NULL”条件,只需使用not predicate:
Foo.includes(:bar).where.not(bars: {id: nil})
Select * from Foo Left Outer Join Bars on .. WHERE bars.id IS NOT NULL
请注意,此语法报告了弃用(它讨论了字符串SQL片段,但我想在解析器中将哈希条件更改为字符串?),因此请务必将引用添加到结尾:
Foo.includes(:bar).where.not(bars: {id: nil}).references(:bar)
弃用警告:看起来您正急切地加载在字符串SQL片段中引用的表(......之一:....)。 例如:
Post.includes(:comments).where("comments.title = 'foo'")
目前,Active Record识别字符串中的表,并且知道将comments表连接到查询,而不是在单独的查询中加载注释。 但是,在不编写完整的SQL解析器的情况下执行此操作本身就存在缺陷。 由于我们不想编写SQL解析器,因此我们将删除此功能。 从现在开始,当您从字符串引用表时,必须明确告诉Active Record:
Post.includes(:comments).where("comments.title = 'foo'").references(:comments)
#2楼
使用Rails 4很容易:
Foo.includes(:bar).where.not(bars: {id: nil})
另见: http : //guides.rubyonrails.org/active_record_querying.html#not-conditions
#3楼
不确定这是否有用,但这对我在Rails 4中有用
Foo.where.not(bar: nil)
#4楼
使用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 })
在使用表之间的作用域时,我更喜欢利用merge
以便我可以更轻松地使用现有作用域。
Foo.includes(:bar).merge(Bar.where.not(id: nil))
此外,由于includes
并不总是选择连接策略,因此您也应该在此处使用references
,否则您最终可能会使用无效的SQL。
Foo.includes(:bar)
.references(:bar)
.merge(Bar.where.not(id: nil))
#5楼
它不是ARel中的错误,它是你逻辑中的一个错误。
你想要的是:
Foo.includes(:bar).where(Bar.arel_table[:id].not_eq(nil))
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3175517