显示未读书籍列表

时间:2013-05-26 09:18:55

标签: sql ruby-on-rails-3

我有一个Book模型,一个User模型和一个Read模型。一本书可以有很多阅读,一个用户可以有很多阅读。基本上,在Read中是某个用户已阅读的所有书籍。

现在我想显示某个用户的所有未读书籍列表。假设用户已登录并且有一个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?

1 个答案:

答案 0 :(得分: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

Tests on 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,这是非常低效的。