I have Categories controller and in layout _menu.html.erb I want to output all categories in home page but I have this error message:
You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occurred while evaluating nil.each
When I logged as a administrator I can add, edit, delete and view all categories.
This is part of my code:
_menu.html.erb
<div class="menu"> <% @categories.each do |category| %> <li> <%= link_to category.title, category %> </li> <% end %> </div>
Categories_controller.rb
def index @title = "All categories" @categories = Category.paginate(:page => params[:page]) end def show @category = Category.find(params[:id]) @title = @category.title end def new @category = Category.new @title = "Add category" end def create @category = Category.new(params[:category]) if @category.save flash[:success] = "Successfully added category" redirect_to categories_path else @title = "Sign up" render 'new' end end def edit @category = Category.find(params[:id]) @title = "Edit category" end def update @category = Category.find(params[:id]) if @category.update_attributes(params[:category]) flash[:success] = "Category updated." redirect_to categories_path else @title = "Edit user" render 'edit' end end def destroy Category.find(params[:id]).destroy flash[:success] = "User destroyed." redirect_to categories_path end
end
-------------Problems Reply------------
@categories
are defined only in the index action. I'm assuming you are using the _menu.html.erb
as a partial in the layout - on every page.
The @categories
will be nil for the others which will cause the exception.
There are basically two ways to define categories for all actions. One would be to do the call in the partial like
<% Category.all.each do |category| %>
The other way using a before filter in your controller
class CategoriesController
before_filter :load_categories
...
private
def load_categories
@categories = Category.all
end
end
I personally prefer the second way because I don't like database calls triggered in views.