宝石子弹说我在为每个加载到页面的食物加载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 partial ..
的渲染行有趣的是,如果我在部分子弹中包含了一个加载器,那就会给我一个错误&#34;未使用的急切加载!&#34;并且第一食物中的膳食食物也被错误地转移到其余的食物中。
此方法如下所示:
在_meal.html.erb ...
中<tbody>
<% mf = MealFood.includes(:meal) %>
<%= render(partial: "meal_foods/meal_food", collection: mf) %>
</tbody>
答案 0 :(得分:5)
将@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)它只运行一个优化的查询来获得他们的饭菜饭菜关系加载...