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