【问题标题】:Eager Loading from nested partial从嵌套的部分渴望加载
【发布时间】:2014-08-30 20:01:03
【问题描述】:

gem 项目符号表示我在为加载到页面的每种膳食食物加载 meal_foods 时出现 N + 1 错误。让我解释一下……

在我的 rails 应用程序中,我有一些嵌套的部分渲染如下:

膳食 > 膳食食品..

因此渲染了多餐,然后对于渲染的每一餐,如果有的话,相应的餐食也会在其中渲染。

这是代码。

用餐/表演内:

<% if @meals != nil %>
   <%= render(partial: "meal", collection: @meals) %>
<% else %>
   <p style="text-align:center">No meals created yet.</p>
<% end %>  

这里是 _meals.html.erb

<tbody>
  <%= render(partial: "meal_foods/meal_food", collection: meal.meal_foods) %>
</tbody>

最后这是 _meal_foods.html.erb 的一部分

<td class="left"><%= meal_food.name %></td>
<td class="left">
  <%= form_for meal_food, action: :update do |f| %>
    <%= f.text_field :servings %>
  <% end %>
</td>  

膳食控制员:

def show
  @meals      = current_client.meals    
  @new_meal   = current_client.meals.build
end 

具体错误:

N+1 Query detected
  Meal => [:meal_foods]
  Add to your finder: :include => [:meal_foods]
N+1 Query method call stack
/app/views/meals/_meal.html.erb:23:in 

此错误指向的行是 _meal.html.erb 部分的渲染行..

有趣的是,如果我在该部分项目符号中包含预加载,则会出现错误“未使用预加载!”并且第一种食物中的膳食食物被错误地转移到其余的膳食中。

这个方法看起来像这样:

在 _meal.html.erb...

<tbody>
  <% mf = MealFood.includes(:meal) %>
  <%= render(partial: "meal_foods/meal_food", collection: mf) %>
</tbody>

【问题讨论】:

  • 将您的 @meals 变量更改为 current_client.meals.includes(:meal_food)
  • 它起作用了,因为没有.includes(:meal_food)@meals 运行1 查询来获取餐点......并且在每个部分(特别是这一行meal.meal_foods)它运行1 个查询每顿饭...所以如果您有n 餐点,则运行1 查询以获取所有餐点,并运行n 查询以获取每顿饭.meal_food (n+1)...如果您使用includes(:meal_food) 它只运行一个优化查询来获取加载了他们的膳食食物关系的膳食...请等待@CWitty 写下答案并标记它:D
  • Ohhh.. 它在一个查询中检索每餐及其对应的餐食?很酷。还有,为什么我的评论被删了? CWitty 的回答值得称赞。我猜谁用这些信息写官方回答我的问题都会得到荣誉。
  • 没有@CWitty 是值得称赞的人
  • 我现在添加它,谢谢:)

标签: ruby-on-rails ruby-on-rails-4 eager-loading partials


【解决方案1】:

将您的 @meals 变量更改为 current_client.meals.includes(:meal_food)。正如@artimees 所说,这渴望加载数据并防止 n+1 查询。它之所以有效,是因为没有 .includes(:meal_food) 的 @meals 运行 1 次查询来获取餐点......并且在每个部分(这一行特别是 meal.meal_foods)中,它为你吃的每一餐运行 1 次查询......所以如果你有 n 餐您运行 1 次查询以获取所有餐点,n 次查询以获取每餐。meal_food (n+1)...如果您使用包含(:meal_food)它只运行一个优化查询来获取他们的餐点餐食关系加载...

【讨论】:

  • 老兄来吧...复制解释并获得代表。你应得的。
猜你喜欢
  • 2013-04-15
  • 2016-08-18
  • 1970-01-01
  • 2020-05-10
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
  • 2015-07-08
  • 1970-01-01
相关资源
最近更新 更多