Rails flash message helper
Asked Answered
C

4

6

I've setup a flash helper:

def flash_message
  flash.each do |key, msg|
    content_tag :div, msg, :id => key, :class => 'flash'
  end
end

And I've put this in my application.html.erb:

<%= flash_message %>

And it's returning content like this:

{:notice=>"Testing"}

I'm fairly new to rails so this could be an amateur mistake.

Concentrated answered 10/9, 2012 at 3:37 Comment(0)
E
11

You're right, it is an amateur mistake. ;)

Using .each here just iterates over the the messages and creates a div for each one. What you want is to make an array out of the divs and then concatenate them together at the end. Something like this:

def flash_message
  flash.map do |key, msg|
    content_tag :div, msg, :id => key, :class => 'flash'
  end.join
end
Enactment answered 10/9, 2012 at 4:8 Comment(0)
P
5

You haven't made any mistakes and by creating a helper, you're reducing the amount of code required to do common things which is great for testing and organization.

One suggestion that I have is that you change your setup and make a shared partial to display the code so it's easier to manage. Then have your helper method just proxy the arguments to the partial function call.

First setup your partial (save it as shared/_flash_messages.html.erb):

<div class="flash-messages">
<% if messages && messages.length > 0 %>
 <% messages.each do |key, message| %>
  <div id="<%= key %>" class="flash"><%= message %></div>
 <% end %>
<% else %>
  No Messages to display
<% end %>
</div>

Then setup your helper methods:

def register_flash_message(key,message)
  flash[key]=message
end

def display_flash_messages()
  render 'shared/flash_messages', :messages => flash
end

This will make things much easier to maintain and customize. You also won't have to deal with having to build your HTML inside of Ruby since everything's stored inside of a partial.

Polygamist answered 10/9, 2012 at 4:59 Comment(0)
M
1

The problem is the return of your helper. You must return the html code in a variable.

With this little change worked for me:

  def flash_message
    html = ""
    flash.each do |key, msg|
      html << (content_tag :div, msg, :id => key, :class => 'flash')
    end
    html
  end

Remember that the last line in ruby it's a return.

Mickeymicki answered 10/9, 2012 at 4:13 Comment(0)
S
0

To get the closing button on the flash message span, you could do something like this: (it can probably be written nicer):

  def flash_helper
    content_tag :div, class: "flash-messages" do
      flash.map do |key, value| 
        content_tag :div, class: "alert alert-dismissable alert-#{key}" do 
          content_tag(:span, '&times;'.html_safe, class: :close, 'data-dismiss' => 'alert') + value
        end
      end.join().html_safe
    end
  end
Sanskrit answered 29/3, 2014 at 16:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.