Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flash messages appearing twice in rails

My flash messages are appearing twice and my web research tells me this is due to render and redirect displaying the messages. I think I need to use flash.now[] or flash[] somewhere to sort this but I can't work out where it needs to go

guidelines_controller.rb

def update
  @guideline = Guideline.find(params[:id])

  respond_to do |format|
    if @guideline.update_attributes(params[:guideline])
      @guideline.update_attribute(:updated_by, current_user.id)
      format.html { redirect_to @guideline, notice: 'Guideline was successfully updated.' }
      format.json { head :no_content }
    else
      format.html { render action: "show" }
      format.json { render json: @guideline.errors, status: :unprocessable_entity }
    end
  end
end

layouts/application.html.erb

<div class="container">

    <% flash.each do |type, message| %>

        <div class="alert <%= flash_class type %>">
            <button class="close" data-dismiss="alert">x</button>
            <%= message %>
        </div>
    <% end %>
</div>

application_helper.rb

def flash_class(type)
  case type
  when :alert
    "alert-error"
  when :notice
    "alert-success"
  else
    ""
  end
end

guideline_controller.rb

def show
    @guideline = Guideline.find(params[:id])
    if @guideline.updated_by
     @updated = User.find(@guideline.updated_by).profile_name
   end

      if User.find(@guideline.user_id)
     @created = User.find(@guideline.user_id).profile_name
      end

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @guideline }

    end
  end
like image 918
tessad Avatar asked Mar 04 '13 01:03

tessad


People also ask

Where are rails flash messages stored?

They are stored in your session store. The default since rails 2.0 is the cookie store, but check in config/initializers/session_store. rb to check if you're using something other than the default.

What is a flash error message?

A flash message is a way to communicate information with the users of your Rails application so they can know what happens as a result of their actions. Example messages: “Password changed correctly” (confirmation) “User not found” (error)

How does flash work rails?

Per the Rails Docs, flash is a middleware method that sends forward temporary datatypes which the Rails controller delegates to the request object. Now in plain English: flash is a method through which you can send a temporary string, array, or hash once between your otherwise stateless HTTP requests.

What is flash in ruby?

The flash is basically a hash that controllers and ERBs can read and write. The flash is part of the session, so the data stored in the flash are specific to a particular user session.


2 Answers

You can do something like this in order to save some lines of code, and display the messages just once:

<%- if flash.any? %>
  <%- flash.keys.each do |flash_key| %>
    <%- next if flash_key.to_s == 'timedout' %>
    <div class="alert-message <%= flash_key %>">
      <a class="close" data-dismiss="alert" href="#"> x</a>
      <%= flash.discard(flash_key) %>
    </div>
  <%- end %>
<%- end %>

By using flash.discard, you show the flash message an avoid rendering twice

like image 66
rorra Avatar answered Sep 18 '22 13:09

rorra


Just putting this here for anyone else having trouble.

I had flash messages appearing twice because I had something in application.html.erb telling my app to display flash messages, but I had previously generated views with rails generate scaffold posts etc, so that had automatically added the flash messages to all the views.

So the solution was to remove them from the views.

Here's a great tutorial that demonstrates removal for just one model/view

So basically, if you have something like this in your application.html.erb:

<% if notice %>
  <p class="alert alert-success"><%= notice %></p>
<% end %>
<% if alert %>
  <p class="alert alert-danger"><%= alert %></p>
<% end %>

Then simply remove the equivalent from each of the views. I.e. remove this line from the top of each view

<p id="notice"><%= notice %></p>
like image 22
stevec Avatar answered Sep 17 '22 13:09

stevec