条件使用NOT NIL的Rails

风格不统一 提交于 2020-02-28 04:13:27

使用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))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!