Rails User.joins.not(...)在Active Record中?

Jam*_*mes 10 sql activerecord ruby-on-rails ruby-on-rails-4

我想在单个SQL查询中查询所有没有评论的用户?

楷模:

class User < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :user
end
Run Code Online (Sandbox Code Playgroud)

所以我想要与此相反:

User.joins.(:comments).group('users.id')
Run Code Online (Sandbox Code Playgroud)

但不是这样的:(因为它生成两个查询)

User.where.not(id: Comment.pluck(:user_id))
Run Code Online (Sandbox Code Playgroud)

也许是这样的?

User.joins.not.(:comments).group('users.id')
Run Code Online (Sandbox Code Playgroud)

感谢您的任何意见!

Dar*_*eng 17

你可以用:

User.includes(:comments).where.not(comments: { id: nil })
Run Code Online (Sandbox Code Playgroud)

这将导致原始SQL看起来像:

SELECT DISTINCT `users`.`*` FROM `users` LEFT OUTER JOIN `comments` ON `comments`.`user_id` = `users`.`id` WHERE `comments`.`id` IS NULL
Run Code Online (Sandbox Code Playgroud)

要通过子查询完成此操作,请参阅以下答案.

旧答案:

你可以做点什么

User.where.not(id: Comment.select(:user_id))
Run Code Online (Sandbox Code Playgroud)

如果您想要一个(尽管是嵌套的)查询.

否则,请查看http://guides.rubyonrails.org/active_record_querying.html#joining-tables以使用外部联接.

  • @thethanghn在这种情况下会导致子查询.每次将`ActiveRecord :: Relation`(这是`select`和`where`返回的活动记录查询方法)传递给查询方法时,都会产生子查询. (2认同)