d11wtq
d11wtq

Reputation: 35308

Trying to use the Rails session flash, but getting nil.[] errors?

<%# Flash-based notifications %>
<% if flash[:error].present? or flash[:notice].present? %>
  <div class="messages <%= flash[:error] ? 'error' : 'notice' %>">
    <ul id="feedback">
      <% if flash[:error].present? %>
        <li><%= flash[:error] %></li>
      <% end %>
      <% if flash[:notice].present? %>
        <li><%= flash[:notice] %></li>
      <% end %>
    </ul>
  </div>
<% end %>

For some reason, as simple as it seems, my attempt to read from the flash inside a partial is producing this error, because the flash is set to nil. Do I need to initialize it manually, or something?

This is Rails 3.1.0. The error is on line 2 of the code snippet, where it tries to access flash[:error].

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.[]

I must be missing something. I'm definitely not overriding it anywhere.

Upvotes: 5

Views: 1156

Answers (1)

Gazler
Gazler

Reputation: 84150

They key here is that you are trying to access the flash inside a partial. You will need to do the following in your render method to pass the flash hash through to the partial:

render YOUR_PARTIAL, :flash => flash

http://guides.rubyonrails.org/layouts_and_rendering.html#passing-local-variables

EDIT:

Easier solution: rename your partial to anything but _flash.

Because your partial was called flash, this happened:

Every partial also has a local variable with the same name as the partial (minus the underscore). You can pass an object in to this local variable via the :object option:

The flash object was being overwritten by a local variable created with the name of the partial.

To clarify this a bit, let's say you have a comment model and you render the comments in the partial, you may do something like:

#_comment.html.erb
<h1>comment.user.name</h1>
<p>comment.body</p>

You would call this partial by doing something along the lines of:

render @customer

Now replace the word customer with flash and you will see why this was an issue.

This functionality that is usually convenience is what caused the issue.

Upvotes: 10

Related Questions