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

问题描述 投票:0回答:2

我有users表,books表和books_users连接表。在users_controller.rb中,我尝试提取具有filtered_books的用户。请帮助我解决该问题。

user.rb

has_many :books_users, dependent: :destroy
has_and_belongs_to_many :books, join_table: :books_users

book.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
ruby-on-rails postgresql ruby-on-rails-5
2个回答
1
投票

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

参见:


-1
投票

[通过查看代码,我假设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)})

© www.soinside.com 2019 - 2024. All rights reserved.