Rails 查询具有 has_many 和 belongs_to 关系的模型
Posted
技术标签:
【中文标题】Rails 查询具有 has_many 和 belongs_to 关系的模型【英文标题】:Rails query for models having has_many and belongs_to relationship 【发布时间】:2013-12-24 16:14:01 【问题描述】:我对 Rails 还很陌生。我有以下型号
class Question < ActiveRecord::Base
has_many :options
has_many :response_parts
end
class ResponsePart < ActiveRecord::Base
belongs_to :question
end
对应的脚手架是
rails g scaffold Question qorder:string qtext:text qtype:string
rails g scaffold ResponsePart answer:string question:belongs_to
现在我想要 qtype 为“移动”的所有响应部分。我尝试了几种方法,但无法成功查询。有人可以告诉一种方法来进行这样的查询。提前致谢。
【问题讨论】:
【参考方案1】:您可以包含两个模型之间的关系并在其上添加约束:
ResponsePart.includes(:question).where(questions: qtype: 'mobile' )
这将从数据库中检索所有与“qtype == 'mobile'
”匹配的问题的 ResponsePart 对象
这也是检索这些记录的最有效方式。
Question.where(qtype: 'mobile').collect(&:response_parts)
这将查询数据库以获取具有“qtype == 'mobile'
”的每个问题的相应 response_parts
示例:如果您有 6 个问题,“qtype == 'mobile'
”,它将为每个问题创建 6 个 SQL 查询。
Question.where(qtype: "mobile").first.response_parts
这只是检索与匹配条件“qtype == 'mobile'
”的第一个问题相关的 ResponsePart 对象
【讨论】:
谢谢。我得到`#<:relation id: answer: question_id: response_id:>, #ResponsePart.includes(:question).where(questions: qtype: 'mobile' )
时。但现在我想访问相应的答案值。当我使用 'ResponsePart.includes(:question).where(questions: qtype: 'mobile' ).each 并尝试使用 .answer 访问值时,它会给出错误未定义的方法answer
。我是否错误地访问了这些值?ResponsePart.includes(:question).where(questions: qtype: 'mobile' ).each do |response_part|
的内容,然后您应该能够通过在 .each 迭代器的块中执行 response_part.answer
来访问答案值 --- 如果您不这样做'不明白这一点,我需要知道你在你的观点中使用的是什么:HAML 或 ERB?那我给你举个例子【参考方案2】:
试试这个
Question.where(qtype: "mobile").first.response_parts
【讨论】:
这不满足要求:它只获取第一个问题的 response_parts,而不是所有问题。 @MrYoshiji 哦,我明白了。是的,你是对的,我误解了这个问题。好渔获【参考方案3】:试试:
Question.where(qtype: 'mobile').collect(&:response_parts)
这将为您提供所有questions
和qtype = 'mobile'
的所有response_parts
更新:(避免 N+1 个查询)
Question.where(qtype: 'mobile').collect(&:response_parts)
这将对每个response_parts
执行一个选择查询,每个question
导致“N+1”个查询。
为了避免“N+1 个查询”,即一个查询来检索问题和 n
查询来检索 resposne_parts
,您可以添加 includes(:join_relation)
(在您的情况下,:join_relation
是 response_parts
)作为如下:
Question.includes(:response_parts).where(qtype: 'mobile').collect(&:response_parts)
【讨论】:
这个没有优化,如果qtype == 'mobile'
有X个问题,它会生成X个SQL查询来检索它们。 (著名的 N+1 查询:***.com/questions/5452340/…)
感谢@MrYoshiji,我已更新我的答案以解决“N+1”查询问题。以上是关于Rails 查询具有 has_many 和 belongs_to 关系的模型的主要内容,如果未能解决你的问题,请参考以下文章
带有 has_many belongs_to 关联的 Rails activerecord 查询
如何在has_many中获取模型的属性:通过Rails 5中的关联
Rails ActiveRecord:三个表 has_many 通过:关联