gpt4 book ai didi

ruby-on-rails - 从嵌套部分预加载

转载 作者:行者123 更新时间:2023-12-04 03:52:32 24 4
gpt4 key购买 nike

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>

膳食 Controller :

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)。正如 @artimees 所说,这会急切地加载数据并阻止 n+1 查询。它之所以有效,是因为没有 .includes(:meal_food) 的 @meals 运行 1 个查询来获取餐食...并且在每个部分(这一行特别是 meal.meal_foods)中,它会为您吃的每顿饭运行 1 个查询...所以如果您有 n 餐,您运行 1 个查询来获取所有餐食,然后运行 ​​n 个查询来获取每顿餐食。meal_food (n+1)...如果您使用includes(:meal_food),它只会运行一个优化查询来获取餐食及其餐食关系已加载...

关于ruby-on-rails - 从嵌套部分预加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24659697/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com