Rails中each_with_index结合cache报错:no block given (yield)求助
Rails视图each_with_index结合cache缓存报错的解决方法
问题场景
我尝试给以下Rails视图代码添加缓存:
<% @equipment.sports.zip(@equipment.sport_equipments).each_with_index do |(sport, equipment), index| %> <% cache[cache_version_tool, equipment.cache_key, sport.cache_key, index] do %> <%= render 'sport', sport: sport, equipment: equipment, cached: true %> <% end %> <% end %>
不使用缓存时代码运行正常,但添加缓存后触发错误:
ActionView::Template::Error (no block given (yield)):
问题原因
错误根源是cache方法的调用方式错误——当需要传入数组作为缓存键时,必须使用方法调用语法(括号),而不是方括号索引语法。方括号写法不会触发缓存块的逻辑,导致内部无法执行yield,最终抛出上述错误。
正确写法
将方括号[]替换为括号(),正确传入缓存键数组并执行缓存块:
<% @equipment.sports.zip(@equipment.sport_equipments).each_with_index do |(sport, equipment), index| %> <% cache([cache_version_tool, equipment.cache_key, sport.cache_key, index]) do %> <%= render 'sport', sport: sport, equipment: equipment, cached: true %> <% end %> <% end %>
额外优化
可以直接传入对象代替手动调用cache_key,Rails会自动处理对象的缓存键生成,同时提取缓存键变量让代码更清晰:
<% @equipment.sports.zip(@equipment.sport_equipments).each_with_index do |(sport, equipment), index| %> <% cache_key = [cache_version_tool, sport, equipment, index] %> <% cache(cache_key) do %> <%= render 'sport', sport: sport, equipment: equipment, cached: true %> <% end %> <% end %>
内容的提问来源于stack exchange,提问作者Chrismisballs
相关产品推荐
相关产品推荐

