Francis's Octopress Blog

A blogging framework for hackers.

The Rails Flash Isn't Just for Messages

The Rails flash isn’t just for messages

The Rails flash is typically used for short messages:

app/controllers/sessions_controller.rb

<code>redirect_to root_url, notice: "You have been logged out."</code>

But it can be used for more than that, any time that you redirect and want to pass along some state without making it part of the URL.

These are some things I’ve used it for.

Identifiers for more complex messages

Maybe you want to show a more complex message after signing up, containing things like links and bullet points.

Rather than send all that in the flash, you can send some identifier that your views know how to handle.

This could be the name of a partial:

app/controllers/users_controller.rb

class UsersController < ApplicationController
  def create
   @user = actually_create_user
   flash[:partial] = "welcome"
   redirect_to some_path
 end
end

  app/views/layouts/application.html.haml

- if flash[:partial]
 = render partial: "shared/flashes/#{flash[:partial]}"
app/views/shared/flashes/_welcome.html.haml
%p Welcome!
 %ul
   %li= link_to("Do this!", this_path)
   %li= link_to("Do that!", that_path)

 

Or just a flag:

 

app/controllers/users_controller.rb

<code>flash[:signed_up] = true redirect_to root_path</code>

app/views/welcomes/show.html.haml

<code>- if flash[:signed_up] %p Welcome!</code>

 

 

 

Pass on the referer

Say you have some filter redirecting incoming requests. Maybe you’re detecting the locale and adding it to the URL, or verifying credentials.

You can use the flash to make sure the redirected-to controller gets the original referer.

 

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
 before_filter :make_locale_explicit

  private
  def make_locale_explicit
    if params[:locale].blank? && request.get?
      flash[:referer] = request.referer
      redirect_to params.merge(locale: I18n.locale)
    end
  end
end

 

 

 

Now, any controller that cares about the referer could get it with:

<code>flash[:referer] || request.referer</code>

Google Analytics events

Say you want to track a Google Analytics event event with JavaScript when a user has signed up. You could do something like this.

Send event data from the controller:

 

app/controllers/users_controller.rb
class UsersController < ApplicationController
  def create
    @user = actually_create_user
    flash[:events] = [ ["_trackEvent", "users", "signup"] ]
    redirect_to some_path
  end
end

 

Then turn it into JavaScript in your view:

 

app/helpers/layout_helper.rb
def analytics_events
  Array(flash[:events]).map do |event|
    "_gaq.push(#{raw event.to_json});"
  end.join("\n")
end

app/views/layouts/application.html.haml

:javascript
  = analytics_events

 

 

 

The flash vs. params

You may have considered that any of the above could have be done with query parameters instead. Including common flash messages:  

app/controllers/sessions_controller.rb
redirect_to root_url(notice: "You have been logged out.")

app/views/layouts/application.html.haml

- if params[:notice]
  %p= params[:notice]

 

Using the flash means that the passed data doesn’t show in the URL, so it won’t happen twice if the link is shared, bookmarked or reloaded. Also the URL will be a little cleaner.

Additionally, the user can’t manipulate the flash, as it’s stored in the session. This adds some protection. If the flash partial example above used params, a user could pass in ../../admin/some_partial to see things they shouldn’t.

Fin

I’d love to hear about what unconventional uses you’ve put the flash to!