2004-11-23 20:04:44 -05:00
|
|
|
module ActionController #:nodoc:
|
|
|
|
# The flash provides a way to pass temporary objects between actions. Anything you place in the flash will be exposed
|
2007-09-09 17:54:59 -04:00
|
|
|
# to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create
|
|
|
|
# action that sets <tt>flash[:notice] = "Successfully created"</tt> before redirecting to a display action that can
|
|
|
|
# then expose the flash to its template. Actually, that exposure is automatically done. Example:
|
2004-11-23 20:04:44 -05:00
|
|
|
#
|
2009-01-18 13:10:58 -05:00
|
|
|
# class PostsController < ActionController::Base
|
2004-11-23 20:04:44 -05:00
|
|
|
# def create
|
|
|
|
# # save post
|
2005-10-16 11:42:03 -04:00
|
|
|
# flash[:notice] = "Successfully created post"
|
2009-01-18 13:10:58 -05:00
|
|
|
# redirect_to posts_path(@post)
|
2004-11-23 20:04:44 -05:00
|
|
|
# end
|
|
|
|
#
|
2009-01-18 13:10:58 -05:00
|
|
|
# def show
|
2004-11-23 20:04:44 -05:00
|
|
|
# # doesn't need to assign the flash notice to the template, that's done automatically
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
2009-01-18 13:10:58 -05:00
|
|
|
# show.html.erb
|
|
|
|
# <% if flash[:notice] %>
|
|
|
|
# <div class="notice"><%= flash[:notice] %></div>
|
|
|
|
# <% end %>
|
2004-11-23 20:04:44 -05:00
|
|
|
#
|
2007-09-09 17:54:59 -04:00
|
|
|
# This example just places a string in the flash, but you can put any object in there. And of course, you can put as
|
|
|
|
# many as you like at a time too. Just remember: They'll be gone by the time the next action has been performed.
|
2005-03-20 14:12:53 -05:00
|
|
|
#
|
|
|
|
# See docs on the FlashHash class for more details about the flash.
|
2004-11-23 20:04:44 -05:00
|
|
|
module Flash
|
2009-05-28 12:35:36 -04:00
|
|
|
extend ActiveSupport::Concern
|
2009-05-20 19:38:48 -04:00
|
|
|
|
2009-06-17 19:23:11 -04:00
|
|
|
include Session
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2005-03-20 14:12:53 -05:00
|
|
|
class FlashNow #:nodoc:
|
2006-02-12 01:11:17 -05:00
|
|
|
def initialize(flash)
|
2005-03-20 14:12:53 -05:00
|
|
|
@flash = flash
|
|
|
|
end
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2005-03-20 14:12:53 -05:00
|
|
|
def []=(k, v)
|
|
|
|
@flash[k] = v
|
|
|
|
@flash.discard(k)
|
|
|
|
v
|
|
|
|
end
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2005-10-26 09:14:10 -04:00
|
|
|
def [](k)
|
|
|
|
@flash[k]
|
|
|
|
end
|
2005-03-20 14:12:53 -05:00
|
|
|
end
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2005-03-20 14:12:53 -05:00
|
|
|
class FlashHash < Hash
|
|
|
|
def initialize #:nodoc:
|
|
|
|
super
|
2009-10-27 02:11:52 -04:00
|
|
|
@used = Set.new
|
2005-03-20 14:12:53 -05:00
|
|
|
end
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2005-03-20 14:12:53 -05:00
|
|
|
def []=(k, v) #:nodoc:
|
|
|
|
keep(k)
|
|
|
|
super
|
|
|
|
end
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2006-02-12 00:51:02 -05:00
|
|
|
def update(h) #:nodoc:
|
2007-05-06 00:17:01 -04:00
|
|
|
h.keys.each { |k| keep(k) }
|
2005-03-20 14:12:53 -05:00
|
|
|
super
|
|
|
|
end
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2006-02-12 00:51:02 -05:00
|
|
|
alias :merge! :update
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2006-02-12 00:51:02 -05:00
|
|
|
def replace(h) #:nodoc:
|
2009-10-27 02:11:52 -04:00
|
|
|
@used = Set.new
|
2005-03-20 14:12:53 -05:00
|
|
|
super
|
|
|
|
end
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2005-03-20 14:12:53 -05:00
|
|
|
# Sets a flash that will not be available to the next action, only to the current.
|
|
|
|
#
|
2005-10-16 11:42:03 -04:00
|
|
|
# flash.now[:message] = "Hello current action"
|
2008-12-15 21:33:21 -05:00
|
|
|
#
|
2005-03-20 14:12:53 -05:00
|
|
|
# This method enables you to use the flash as a central messaging system in your app.
|
|
|
|
# When you need to pass an object to the next action, you use the standard flash assign (<tt>[]=</tt>).
|
|
|
|
# When you need to pass an object to the current action, you use <tt>now</tt>, and your object will
|
|
|
|
# vanish when the current action is done.
|
|
|
|
#
|
|
|
|
# Entries set via <tt>now</tt> are accessed the same way as standard entries: <tt>flash['my-key']</tt>.
|
|
|
|
def now
|
2007-09-09 17:54:59 -04:00
|
|
|
FlashNow.new(self)
|
2005-03-20 14:12:53 -05:00
|
|
|
end
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2005-03-20 14:12:53 -05:00
|
|
|
# Keeps either the entire current flash or a specific flash entry available for the next action:
|
|
|
|
#
|
|
|
|
# flash.keep # keeps the entire flash
|
2005-10-16 11:42:03 -04:00
|
|
|
# flash.keep(:notice) # keeps only the "notice" entry, the rest of the flash is discarded
|
2006-09-03 19:22:24 -04:00
|
|
|
def keep(k = nil)
|
2005-03-20 14:12:53 -05:00
|
|
|
use(k, false)
|
|
|
|
end
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2007-08-31 15:07:42 -04:00
|
|
|
# Marks the entire flash or a single flash entry to be discarded by the end of the current action:
|
2005-03-20 14:12:53 -05:00
|
|
|
#
|
2007-05-28 22:42:31 -04:00
|
|
|
# flash.discard # discard the entire flash at the end of the current action
|
|
|
|
# flash.discard(:warning) # discard only the "warning" entry at the end of the current action
|
2006-09-03 19:22:24 -04:00
|
|
|
def discard(k = nil)
|
2005-03-20 14:12:53 -05:00
|
|
|
use(k)
|
|
|
|
end
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2005-03-20 14:12:53 -05:00
|
|
|
# Mark for removal entries that were kept, and delete unkept ones.
|
|
|
|
#
|
|
|
|
# This method is called automatically by filters, so you generally don't need to care about it.
|
|
|
|
def sweep #:nodoc:
|
2008-12-15 21:33:21 -05:00
|
|
|
keys.each do |k|
|
2009-10-27 02:11:52 -04:00
|
|
|
unless @used.include?(k)
|
|
|
|
@used << k
|
2005-03-20 14:12:53 -05:00
|
|
|
else
|
|
|
|
delete(k)
|
|
|
|
@used.delete(k)
|
|
|
|
end
|
2004-11-23 20:04:44 -05:00
|
|
|
end
|
2006-09-03 19:22:24 -04:00
|
|
|
|
2007-09-09 17:54:59 -04:00
|
|
|
# clean up after keys that could have been left over by calling reject! or shift on the flash
|
2009-10-27 02:11:52 -04:00
|
|
|
(@used - keys).each{ |k| @used.delete(k) }
|
2005-03-20 14:12:53 -05:00
|
|
|
end
|
2008-12-15 21:33:21 -05:00
|
|
|
|
2009-10-27 02:11:52 -04:00
|
|
|
def store(session)
|
2009-05-28 10:30:49 -04:00
|
|
|
return if self.empty?
|
2009-10-27 02:11:52 -04:00
|
|
|
session["flash"] = self
|
2009-05-28 10:30:49 -04:00
|
|
|
end
|
|
|
|
|
2009-10-27 02:11:52 -04:00
|
|
|
private
|
|
|
|
# Used internally by the <tt>keep</tt> and <tt>discard</tt> methods
|
|
|
|
# use() # marks the entire flash as used
|
|
|
|
# use('msg') # marks the "msg" entry as used
|
|
|
|
# use(nil, false) # marks the entire flash as unused (keeps it around for one more action)
|
|
|
|
# use('msg', false) # marks the "msg" entry as unused (keeps it around for one more action)
|
|
|
|
# Returns the single value for the key you asked to be marked (un)used or the FlashHash itself
|
|
|
|
# if no key is passed.
|
|
|
|
def use(key = nil, used = true)
|
|
|
|
Array(key || keys).each { |k| used ? @used << k : @used.delete(k) }
|
|
|
|
return key ? self[key] : self
|
|
|
|
end
|
2005-03-20 14:12:53 -05:00
|
|
|
end
|
2005-11-21 13:09:28 -05:00
|
|
|
|
2009-06-17 19:23:11 -04:00
|
|
|
protected
|
|
|
|
def process_action(method_name)
|
|
|
|
super
|
2009-10-27 02:11:52 -04:00
|
|
|
@_flash.store(session) if @_flash
|
|
|
|
@_flash = nil
|
2009-05-20 19:38:48 -04:00
|
|
|
end
|
|
|
|
|
2009-06-17 19:23:11 -04:00
|
|
|
def reset_session
|
|
|
|
super
|
2009-10-27 02:11:52 -04:00
|
|
|
@_flash = nil
|
2009-06-17 19:23:11 -04:00
|
|
|
end
|
2009-05-20 19:38:48 -04:00
|
|
|
|
2009-06-17 19:23:11 -04:00
|
|
|
# Access the contents of the flash. Use <tt>flash["notice"]</tt> to
|
|
|
|
# read a notice you put there or <tt>flash["notice"] = "hello"</tt>
|
|
|
|
# to put a new one.
|
|
|
|
def flash #:doc:
|
2009-10-27 02:11:52 -04:00
|
|
|
unless @_flash
|
2009-06-17 19:23:11 -04:00
|
|
|
@_flash = session["flash"] || FlashHash.new
|
|
|
|
@_flash.sweep
|
2009-05-20 19:38:48 -04:00
|
|
|
end
|
2009-06-17 19:23:11 -04:00
|
|
|
|
|
|
|
@_flash
|
|
|
|
end
|
2004-11-23 20:04:44 -05:00
|
|
|
end
|
2007-10-02 01:32:14 -04:00
|
|
|
end
|