我正在练习一本书的教程。在本教程中;一些视图中需要显示来自少数模型的所有值。这些实例变量是在sidebar_values
:
application_controller.rb
方法下定义的
helper_method :sidebar_values
def sidebar_values
@food_prefs = FoodPreference.all
@food_types = FoodType.all
@cuisines = Cuisine.all
end
以下是application.html.erb
:
<div class="col-lg-2">
<div class="panel panel-primary" id="panels">
<div class="panel-heading">
Food Preferences
</div>
<% @food_prefs.each do |p| %> #42, error begins here
<p><%= p.name %></p>
<% end %>
</div>
<div class="panel panel-primary" id="panels">
<div class="panel-heading">
Food Types
</div>
<% @food_types.each do |t| %>
<p><%= t.name %></p>
<% end %>
</div>
<div class="panel panel-primary" id="panels">
<div class="panel-heading">
Cuisines
</div>
<% @cuisines.each do |c| %>
<p><%= c.name %></p>
<% end %>
</div>
</div>
当我试图在视图中调用这些变量时,它会抛出这样的错误:
NoMethodError - undefined method `each' for nil:NilClass:
app/views/layouts/application.html.erb:42:in `_app_views_layouts_application_html_erb___4138475832854219665_70001190164060'
这些变量中的值不是nil
,但我无法从任何视图调用这些变量。
答案 0 :(得分:3)
我知道你正在关注一个教程,但我认为有些东西缺失了:
# application_controller.rb
before_filter :sidebar_values
def sidebar_values
@food_prefs = FoodPreference.all
@food_types = FoodType.all
@cuisines = Cuisine.all
end
此before_filter :sidebar_values
会在调用的每个操作上调用方法sidebar_values
。您可以仅指定/ except选项来过滤受影响的操作:
before_filter :sidebar_values, except: [:login, :logout]
此外,我会为此方法使用更好的名称,例如set_sidebar_variables
,因为它正在为侧边栏设置实例变量。
正如我在评论中所解释的那样,我认为您不需要将其作为辅助方法,IMO helper_method :sidebar_values
可以被移除。
另一件事是您的SQL查询没有限制,您只需查询所有3个模型。这在长期来看并不好。如果您有数百种美食,FoodTypes和FoodPrefs怎么办?我会添加一个.limit(x)
来防止这种情况发生:
def sidebar_values
@food_prefs = FoodPreference.limit(10)
@food_types = FoodType.limit(10)
@cuisines = Cuisine.all
end
答案 1 :(得分:0)
undefined method 'each' for nil:NilClass:
<% @food_prefs.each do |p| %>
@food_prefs
的原因是因为each
变量为零。你在一个nil变量@food_prefs
上调用一个方法:rails console
。基本上,如果您打开FoodPreference.count
并查询zero
,则会返回<% if @food_prefs %>
<% @food_prefs.each do |p| %>
<p><%= p.name %></p>
<% end %>
<% end %>
次。{要解决此问题,请在数据库中创建此类的实例,以使计数不再为零。
或者:
将if语句包装起来。像这样的东西:
if statement
如果您确定@food_prefs
已不再nil
Helper
如何在辅助方法中定义变量:
虽然在这种情况下您可能不需要定义辅助方法,但您可以在@
文件夹中的文件中定义它们。它是一个直接的红宝石。只需创建可在视图中调用的方法。与控制器方法不同,您不需要helpers
符号。您的{{1}}内创建的方法可在您的视图中使用。