Ответ 1
Post.where("id not in (select post_id from users)")
Итак, у меня есть почта и пользователь.
Опубликовать has_many пользователей и пользователя принадлежит к сообщению.
Мне нужна находка, которая найдет все сообщения, которые не имеют таких пользователей, как:
Post.first.users
=> []
Post.where("id not in (select post_id from users)")
Узнал об этом только сегодня:
Post.eager_load(:users).merge(User.where(id: nil))
Работает с Rails 4+ как минимум.
Update:
В Rails 5+ вместо этого можно использовать left_joins
:
Post.left_joins(:users).merge(User.where(id: nil))
Если вам нужно что-то быстрое, используйте инструкцию SQL, например:
SELECT *
FROM posts p
LEFT OUTER JOIN users u ON p.id = u.post_id
WHERE u.id IS null
что-то вроде этого:
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)
Post.first.users.empty?
должно быть достаточно, если пользователи возвращают массив.
Если вы хотите проверить каждый пост, который вы могли бы сделать
Post.each do |p|
if p.users.empty?
do whatever
end
end
Я предполагаю, что sql с может вызвать проблемы с производительностью, если в таблице базы данных много строк. осторожно с этим
Я знаю, что это помечено как Rails 3, но если вы используете Rails 4, я делаю это так.
Post.where.not(user_id: User.pluck(:id))