私は投稿とユーザーを持っています。
投稿は投稿数が多く、ユーザーは投稿に所属しています。
私は次のような任意のユーザーを持っていけない、すべての記事を検索します検索を必要とする:ユーザーが配列を返す場合アソシエーション内にあるすべてが見つからない
Post.first.users
=> []
私は投稿とユーザーを持っています。
投稿は投稿数が多く、ユーザーは投稿に所属しています。
私は次のような任意のユーザーを持っていけない、すべての記事を検索します検索を必要とする:ユーザーが配列を返す場合アソシエーション内にあるすべてが見つからない
Post.first.users
=> []
Post.where("id not in (select post_id from users)")
Post.first.users.empty?
は十分なはずです。
SELECT *
FROM posts p
LEFT OUTER JOIN users u ON p.id = u.post_id
WHERE u.id IS null
は、のようなSQL文を採用して行うことができますinを使用すると、データベース表に多数の行がある場合にパフォーマンスの問題が発生する可能性があります。そのようなこと
は、私はSQLを推測:あなたは、各ポストをチェックしたい場合は
あなたは高速で何かが必要な場合
Post.each do |p|
if p.users.empty?
do whatever
end
end
右。最も読みやすいコードから始め、テストでそのコードを保護してから、パフォーマンスを最適化することができます。テストがなければ、偶然にいくつかのレコードを「最適化」するリスクがあります。そして、常に実際のパフォーマンスを測定してください:最適化されたバージョンが常に最速であるとは限りません。 – Arsen7
何かに注意してください:
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.eager_load(:users).merge(User.where(id: nil))
作品4+少なくとも:
Post.where.not(user_id: User.pluck(:id))
はこのちょうど今日のことを学びました。
更新:
Railsの5+では、あなたの代わりにleft_joins
を使用することができます。
Post.left_joins(:users).merge(User.where(id: nil))
サブクエリにはnilが含まれていれば、何も返されず、私の場合に必要だったように、' NOT EXISTS'を代わりに使いたいかもしれません。 [さらに読む](http://stackoverflow.com/questions/173041/not-in-vs-not-exists)。 – manafire