我有一个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?
答案 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
在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,这是非常低效的。