使用连接表中的 rails 查询提取数据



我有用户表,书籍表和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)})

最新更新