返回一系列作者书籍,多对多关系

Posted

技术标签:

【中文标题】返回一系列作者书籍,多对多关系【英文标题】:Return an array of books of authors, many to many relationship 【发布时间】:2021-01-11 19:22:10 【问题描述】:

我有两个模型,Author 和 Book 以及一个中间表 middleItem。存在多对多关系。我的任务是创建一个变量@myBooks,它返回作者拥有的所有书籍的数组。但是,我们将在会话 session[:user_id] 中按作者 id 搜索

class middleItem < ApplicationRecord
  belongs_to :author
  belongs_to :book
end

class Book < ApplicationRecord
  has_many :middleItem
  has_many :author, through: :middleItem
end

class Author < ApplicationRecord
  has_many :middleItem
  has_many :books, through: :middleItem
end

但它不起作用

Book.joins(:authors).joins(:middleItem).where(middleItem: user_id: session[:user_id]).distinct.map |x| puts x.name

编辑: 作者:(1)莎士比亚,(2)奥威尔 书籍:(1)罗密欧与朱丽叶,(2)哈姆雷特,(3)动物农场

中表:(1,1), (1,2), (2,3)

@myBooks 应该是:“罗密欧与朱丽叶,哈姆雷特”如果我们说 session[:user_id] 是 1

【问题讨论】:

除了需要一些工作的查询之外,我认为您的图书模型中有错字,它应该说:作者 不确定我是否理解其中的某些部分,但纯粹基于您的代码Book.joins(:authors).where(authors: id: session[:user_id]) 就足够了。旁注:map |x| x.any_db_attribute_here 始终可以缩写为 pluck(:any_db_attribute_here) 感谢您的帮助。我试图让事情更清楚,检查编辑 @engineersmnky 这很完美,谢谢! 【参考方案1】:

我认为使用scopes 非常适合这个问题,您可以在book 模型中定义范围,如下所示:

scope :search_by_author, ->(author_id)  joins(:authors).where(Author.arel_table[:id].eq(author_id)).distinct

上面可以像这样使用:Book.search_by_author(1),如果你真的需要一个数组而不是 ActiveRecord 结果,你可以将结果转换为数组:Book.search_by_author(1).to_a

希望以上内容有所帮助! ?

【讨论】:

一些建设性的cmets:1)你可以使用Author.arel_attribute(:id)而不是Author.arel_table[:id]; 2) 对于简单的用例,例如相等 where(table_name: column_name: value) 通常被认为比使用 Arel 更惯用; 3) + [] 是将ActiveRecord::Relation 转换为Array 而不是使用to_a 的尴尬方式。 感谢 cmets @ngineersmnky,将编辑我的答案,因此更有用/更清晰,尽管我更喜欢保留 arel_table 方法 thx ?

以上是关于返回一系列作者书籍,多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

如何从多对多表中选择一对一关系

如何在graphql突变中设置多对多关系?

春季 JPA |在多对多关系中搜索

Prisma:在显式多对多关系中创建或连接记录

django ORM多对多正向查询时查询返回结果为None

查询显示多对多关系中的关联列表