首页 > 解决方案 > 使用 rails 查询从连接表中提取数据

问题描述

我有 users 表、 books 表和 books_users 加入表。在 users_controller.rb 中,我正在尝试提取已过滤的用户。请帮我解决这个问题。

用户.rb

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

书本.rb

has_and_belongs_to_many :users

book_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-railspostgresqlruby-on-rails-5

解决方案


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

看:


推荐阅读