【问题标题】:Rails query for models having has_many and belongs_to relationshipRails 查询具有 has_many 和 belongs_to 关系的模型
【发布时间】: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 为“移动”的所有响应部分。我尝试了几种方法,但无法成功查询。有人可以告诉一种方法来进行这样的查询。提前致谢。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4


    【解决方案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)
    

    这将为您提供所有questionsqtype = '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_relationresponse_parts)作为如下:

    Question.includes(:response_parts).where(qtype: 'mobile').collect(&:response_parts)
    

    【讨论】:

    • 这个没有优化,如果qtype == 'mobile'有X个问题,它会生成X个SQL查询来检索它们。 (著名的 N+1 查询:stackoverflow.com/questions/5452340/…
    • 感谢@MrYoshiji,我已更新我的答案以解决“N+1”查询问题。
    猜你喜欢
    • 1970-01-01
    • 2015-10-15
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多