我有用户表,书籍表和books_users连接表。在 users_controller.rb 中,我正在尝试提取具有filtered_books的用户。请帮助我解决这个问题。
用户.rb
has_many :books_users, dependent: :destroy
has_and_belongs_to_many :books, join_table: :books_users
书.rb
has_and_belongs_to_many :users
books_user.rb
belongs_to :user
belongs_to :book
users_controller.rb
def filter_users
@filtered_books = Fiction.find(params[:ID]).books
@users = **I want only those users who have filtered_books**
end
has_and_belongs_to_many
实际上并不使用连接模型。您正在寻找的是has_many through:
class User < ApplicationRecord
has_many :book_users
has_many :books, through: :book_users
end
class Book < ApplicationRecord
has_many :book_users
has_many :users, through: :book_users
end
class BookUser < ApplicationRecord
belongs_to :book
belongs_to :user
end
如果要向书籍添加类别,可以通过添加类别模型和另一个连接表来实现。不是通过创建一个Fiction
模型,如果你想要多个类别,它只会创建大量的代码重复。
class Book < ApplicationRecord
has_many :book_users
has_many :users, through: :book_users
has_many :book_categories
has_many :categories, through: :book_categories
end
class BookCategory < ApplicationRecord
belongs_to :book
belongs_to :category
end
class Category < ApplicationRecord
has_many :book_categories
has_many :books, through: :book_categories
end
如果要查询关注特定书籍的用户,可以通过在书籍上使用带有条件的内部联接来实现:
User.joins(:books)
.where(books: { title: 'Lord Of The Rings' })
如果您想获取具有特定类别的图书:
Book.joins(:categories)
.where(categories: { name: 'Fiction' })
然后对于大结局 - 要查询与至少一本归类为"小说"的书相关的用户,您将执行以下操作:
User.joins(books: :categories)
.where(categories: { name: 'Fiction' })
# or if you have an id
User.joins(books: :categories)
.where(categories: { id: params[:category_id] })
您还可以添加间接关联,以便直接从类别转到用户:
class Category < ApplicationRecord
# ...
has_many :users, though: :books
end
category = Category.includes(:users)
.find(params[:id])
users = category.users
看:
- has_many:通过协会
- 加入嵌套的关联。
- 指定连接表的条件
通过查看代码,我假设Book
模型也具有fiction_id
,因为此行中显示的has_many
关联Fiction.find(params[:ID]).books
。可能有两种方法可以实现这一点。第一个可能是您使用@filtered_books
变量并从中提取用户,就像@filtered_books.collect {|b| b.users}.flatten
提取所有用户一样。第二种方法可能是通过使用fiction_id
的关联,这可能是User.joins(:books).where(books: {id: @filtererd_books.pluck(:id)})