使用 Rails 查询急切加载
Posted
技术标签:
【中文标题】使用 Rails 查询急切加载【英文标题】:Eager Loading with Rails Query 【发布时间】: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
但我认为这是低效的,并且认为通过预先加载可能有更快的方法来执行此操作(这会为项目中的每个步骤创建一个查询)。有人对如何做到这一点有建议吗?
【问题讨论】:
【参考方案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 将问题与项目联系起来以上是关于使用 Rails 查询急切加载的主要内容,如果未能解决你的问题,请参考以下文章