5

I was trying to clean up application.html.erb, by moving parts of the layout into partials. I had the following code for handling flash errors/notifications:

<div id="flash">
  <% if flash[:notice] %>
    <h3 class="info_box"><%= flash[:notice] %></h3>
  <% end %>
  <% if flash[:error] %>
    <h3 class="error_box"><%= flash[:error] %></h3>
  <% end %> 
</div>

This code worked fine in application.html.erb, until I moved it into a file called "_flash.html.erb" and replaced it with the following:

<%= render 'layouts/flash' %>

In the partial the flash hash was not a recognized object and causes a "You have a nil object when you didn't expect it!" error.

I've move the code back to application.html.erb and all is good. But I couldn't find an answer for accessing the flash hash within a partial. Looking at the Rails Guide for "Rendering and Layouts" I can see that there are various ways for render() to pass variables into the partial, but I was unsuccessful in figuring it out. Any ideas?

Don Leatham
  • 2,694
  • 4
  • 29
  • 41
  • Did you try `<%= render :partial => 'layouts/flash' %>` ? Also, where are you calling this `render` from ? And keep that partial out of layouts I would say. – Zabba Nov 05 '11 at 21:26
  • You could definitely provide local variables to the partial like this: `render 'layouts/flash, :locals => {:flash => flash}`. But I don't know if this is really the best option. – topek Nov 05 '11 at 21:33
  • Zabba and Topek - thanks for the suggestions, unfortunately neither work. Both suggestions lead to: "You have a nil object..." This really is perplexing! – Don Leatham Nov 06 '11 at 06:56

2 Answers2

17

Goliatone's solution seemed to work, but in the end it didn't. I found out that the reason this was not working for me was that I had named my partial _flash. Apparently Rails creates a local variable for the partial using the partial's name (without the "_" character.) So I had a variable clash. As soon as I change the name of the partial to something other than _flash everything worked perfectly. I found the answer here: Rails flash[:notice] always nil

Community
  • 1
  • 1
Don Leatham
  • 2,694
  • 4
  • 29
  • 41
1

You can place the conditional check for flash in the layout, and if it exists then render the partial:

<%= render 'layouts/flash' unless flash.nil?%>

Then, if it exists it will get rendered as expected.

goliatone
  • 2,183
  • 16
  • 29
  • Thanks goliatone! This works great, but it is confusing to me. Ruby/Rails does not issue a nil-object error for "if flash[:notice]" while it is in application.html.erb, but when "if flash[:notice]" is in a partial, it will issue a nil-object error! Very strange! Why is that? – Don Leatham Jan 17 '12 at 04:54
  • 1
    flash is an Object *, @closed=false, @flashes={}, @now=nil>* ... so it won't be nil.. even if no flash message – equivalent8 Jun 14 '12 at 08:32