1

Book モデル、User モデル、Read モデルがあります。Book は多くの Read を持つことができ、User は多くの Read を持つことができます。基本的に、Read には、特定の User が読んだすべての本があります。

ここで、特定のユーザーのすべての未読本のリストを表示したいと考えています。ユーザーがログインしていて current_user オブジェクトがあると仮定すると、そのようなリストを取得するにはどうすればよいでしょうか?

私は現在これを持っています:

@unread_books = Book.find(:all, include: :reads, conditions: ["books.id NOT IN (?)", current_user.read_ids])

しかし、これは書籍 ID を読み取り ID にマップします。次のようになります。

conditions: ["books.id NOT IN (?)", current_user.read_book_ids]

しかし、これはエラーになります:

undefined method `read_book_ids' for #<User:0x007fb21782b3f8>

では、ブック ID を Read の外部キーのブック ID にマップするにはどうすればよいでしょうか。

4

1 に答える 1

1

これらの本を取得するには、 LEFT OUTER JOINを使用します。現在のユーザー ID で読んだ本、または読んだ本。次に、外部結合に含まれる (内部結合には含まれない) ユーザーが関連付けられていないブックのみを選択します。これらはまさに現在のユーザーが読んでいない本です:

SELECT books.id, books.title FROM books
LEFT OUTER JOIN readings 
  ON readings.book_id = books.id 
  AND readings.user_id = 1
WHERE readings.user_id IS NULL

SQLFiddle でテストします。

Rails では、これは次のようになります (テストされていません)。

Books.joins("LEFT OUTER JOIN reads\
  ON reads.book_id = books.id\
  AND reads.user_id = :user_id", user_id: current_user.id)
.where("reads.user_id IS NULL")

あなたのアプローチの問題は、無視する非常に大きなIDの配列を渡している可能性があることです。これは、各エントリの ID を検索する必要があり、非常に非効率的です。

于 2013-05-26T09:30:19.423 に答える