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