【发布时间】:2011-02-09 16:43:03
【问题描述】:
所以我有一个帖子和一个用户。
帖子有_许多用户和一个用户属于_一个帖子。
我需要一个查找来查找所有没有任何用户的帖子,如下所示:
Post.first.users
=> []
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3
所以我有一个帖子和一个用户。
帖子有_许多用户和一个用户属于_一个帖子。
我需要一个查找来查找所有没有任何用户的帖子,如下所示:
Post.first.users
=> []
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3
Post.where("id not in (select post_id from users)")
【讨论】:
NOT EXISTS 代替,就像我在特定情况下需要的那样。 Further reading.
今天才学这个:
Post.eager_load(:users).merge(User.where(id: nil))
至少适用于 Rails 4+。
更新:
在 Rails 5+ 中,您可以改用 left_joins:
Post.left_joins(:users).merge(User.where(id: nil))
【讨论】:
类似的东西:
p = Post.arel_table
u = User.arel_table
posts = Post.find_by_sql(p.join(u).on(p[:user_id].eq(u[:p_id])).where(u[:id].eq(nil)).to_sql)
【讨论】:
我知道这被标记为 Rails 3,但如果您使用的是 Rails 4,我一直在这样做。
Post.where.not(user_id: User.pluck(:id))
【讨论】:
如果您需要快速的东西,请使用如下 SQL 语句:
SELECT *
FROM posts p
LEFT OUTER JOIN users u ON p.id = u.post_id
WHERE u.id IS null
【讨论】:
我猜如果数据库表有很多行,带有 in 的 sql 可能会导致性能问题。小心点
【讨论】:
如果用户返回一个数组,Post.first.users.empty? 应该足够了。
如果您想检查每个帖子,您可以这样做
Post.each do |p|
if p.users.empty?
do whatever
end
end
【讨论】:
Post.each do |p| if p.users == nil do whatever end end