【问题标题】:Eager Loading with Rails Query使用 Rails 查询急切加载
【发布时间】:2014-10-23 18:44:33
【问题描述】:

在我的 Rails 应用中,项目有很多步骤,步骤可以有问题

我想编写一个方法来检查项目是否有任何问题,并返回带有问题的步骤的 id。

目前,我的 project.rb

中有以下内容
 def step_with_question
    question_step = ""
    steps.order(:published_on).each do |step|
      if step.question
        question_step = step.id
      end
    end
    return question_step
  end

但我认为这是低效的,并且认为通过预先加载可能有更快的方法来执行此操作(这会为项目中的每个步骤创建一个查询)。有人对如何做到这一点有建议吗?

【问题讨论】:

    标签: ruby-on-rails activerecord eager-loading


    【解决方案1】:

    您可以使用joins 只返回关联的:steps,它们实际上与它们有:questions 关联:

    @project = Project.joins(steps: :questions).order('steps.published_on').find(id)
    

    此查询将仅返回实际具有相关问题的项目步骤。您现在可以安全地遍历步骤记录并返回或使用step.id

    @project.steps.each do |step|
      question_step = step.id
      # do something with the question_step
    end
    

    【讨论】:

      【解决方案2】:

      我不明白你的代码究竟做了什么,但是如果你想从一个步骤访问一个问题,你可以使用方法includes

      project = Project.find(id) # Get a product just to show how it works
      # To tell Rails to make a single query when you want to
      # access the questions, do something like this:
      steps_with_questions = project.steps.includes(:question)
      

      这样,当您尝试访问一个问题时,它就会被加载。

      使用这些的最佳方法是为step.rb 编写一个作用域,如下所示:

      scope :with_questions, lambda { includes :questions }
      

      现在你只需要调用:

      project.steps.with_questions
      

      使代码更易于阅读。

      编辑:您的代码如下所示:(没有我之前提到的范围)

       def step_with_question
          question_step = ""
          steps.order(:published_on).includes(:question).each do |step|
            if step.question
              question_step = step.id
            end
          end
          return question_step
        end
      

      【讨论】:

      • 你可以考虑 has_many :through 将问题与项目联系起来
      猜你喜欢
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-06
      • 1970-01-01
      相关资源
      最近更新 更多