Answers:
使用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))
rails undefined method 'not_eq' for :confirmed_at:Symbol
..
where
条件只是在构建AST,直到您按下诸如each
或的终端方法,它才会访问数据库to_a
。建立查询与性能无关;您从数据库中请求的是。
这不是ARel中的错误,而是逻辑上的错误。
您想要的是:
Foo.includes(:bar).where(Bar.arel_table[:id].not_eq(nil))
true
,这是一个布尔值。:id => true
使您id = 1
掌握SQLese。
field_name != 'NULL'
。
id = 't'
:)
对于Rails4:
因此,您想要的是内部联接,因此您实际上应该只使用联接谓词:
Foo.joins(:bar)
Select * from Foo Inner Join Bars ...
但是,为了记录在案,如果您想要“ NOT NULL”条件,只需使用not谓词:
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)
DEPRECATION警告:您似乎渴望加载在字符串SQL代码段中引用的表(其中一个:....)。例如:
Post.includes(:comments).where("comments.title = 'foo'")
当前,Active Record可以识别字符串中的表,并且知道将注释表加入查询中,而不是在单独的查询中加载注释。但是,在不编写成熟的SQL分析器的情况下执行此操作本质上是有缺陷的。由于我们不想编写SQL解析器,因此我们将删除此功能。从现在开始,当您从字符串引用表时,必须显式告知Active Record:
Post.includes(:comments).where("comments.title = 'foo'").references(:comments)
references
呼叫帮我!
不确定这是否有帮助,但这在Rails 4中对我有用
Foo.where.not(bar: nil)
使用Rails 4,很容易:
Foo.includes(:bar).where.not(bars: {id: nil})
另请参阅:http : //guides.rubyonrails.org/active_record_querying.html#not-conditions
!nil
true
在Ruby中评估为,在SQL查询中ARel转换true
为1
。因此,生成的查询实际上就是您要的内容-这不是ARel错误。