21

The ability to have flash messages (notice, error, warning, etc) with embedded links is nice from a user interaction standpoint. However, embedding an anchor tag inside a flash message from the controller is dirty.

Let's assume that a flash message like this is good for usability*:

Example Flash Message Notice with an Embedded Link http://img.skitch.com/20090826-xbsa4tb3sjq4fig9nmatakthx3.png (borrowed from DailyMile.com)

What tactic would you take between the controller and view to employ something like this cleanly?

Ryan McGeary
  • 235,892
  • 13
  • 95
  • 104

3 Answers3

24

Just thought I would share this, since found answer I was looking for elsewhere:

Works on rails 3.1

flash[:notice] = "Proceed to #{view_context.link_to('login page', login_path)}".html_safe
jjnevis
  • 2,672
  • 3
  • 22
  • 22
  • Making this as the new accepted answer. This is much more clear than the approach I was taking before. I wasn't aware of the `view_context` accessor. – Ryan McGeary Jan 27 '12 at 16:18
  • 2
    view_context works in all Rails 3 versions. It's been introduced in 3.0.0 according to http://apidock.com/rails/AbstractController/Rendering/view_context – Slobodan Kovacevic Feb 20 '12 at 11:04
8

Glenn Gillen has an approach that he calls Useful Flash Messages in Rails.

I modified his code snippets to be a little more idiomatic (for me at least).

The controller fills the flash like this:

flash[:notice]      = "Your profile was updated. %s"
flash[:notice_item] = ["Edit again?", edit_profile_path(@profile)]

You then might have helpers that look something like this:

def render_flash_messages(*keys)
  messages = keys.collect do |key|
    content_tag(:p, flash_message_with_item(key), :class => "flash #{key}") if flash[key]
  end.join
  content_tag(:div, messages, :id => "flash_messages") unless messages.blank?
end

def flash_message_with_item(key)
  item = flash["#{key}_item".to_sym]
  substitution = item.is_a?(Array) ? link_to(*item) : item
  flash[key] % substitution
end

The view looks simply like this:

<%= render_flash_messages(:error, :notice, :warning) %>

The view (via the flash_message_with_item helper) is responsible for creating the anchor tag, but the controller manages what goes into the flash message including an optional resource for further action.

Ryan McGeary
  • 235,892
  • 13
  • 95
  • 104
1

You could create a helper method to render out partials based on the value passed back in the flash message.

Mike Buckbee
  • 6,793
  • 2
  • 33
  • 36
  • This almost feels like too much separation. Also where do you manage which object or path should be linked to without relying on global-like instance variables within the partials? – Ryan McGeary Aug 26 '09 at 13:09