rails4 app中实例变量的未定义方法错误

时间:2014-05-09 13:40:55

标签: ruby-on-rails ruby-on-rails-4 helper activemodel

我正在练习一本书的教程。在本教程中;一些视图中需要显示来自少数模型的所有值。这些实例变量是在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,但我无法从任何视图调用这些变量。

2 个答案:

答案 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}}内创建的方法可在您的视图中使用。