aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/middleware/flash.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/middleware/flash.rb')
-rw-r--r--actionpack/lib/action_dispatch/middleware/flash.rb75
1 files changed, 50 insertions, 25 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb
index 89003e7a5e..59639a010e 100644
--- a/actionpack/lib/action_dispatch/middleware/flash.rb
+++ b/actionpack/lib/action_dispatch/middleware/flash.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/hash/keys'
+
module ActionDispatch
class Request < Rack::Request
# Access the contents of the flash. Use <tt>flash["notice"]</tt> to
@@ -8,7 +10,7 @@ module ActionDispatch
end
end
- # The flash provides a way to pass temporary objects between actions. Anything you place in the flash will be exposed
+ # The flash provides a way to pass temporary primitive-types (String, Array, Hash) between actions. Anything you place in the flash will be exposed
# 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] = "Post successfully created"</tt> before redirecting to a display action that can
# then expose the flash to its template. Actually, that exposure is automatically done.
@@ -35,8 +37,11 @@ module ActionDispatch
# flash.alert = "You must be logged in"
# flash.notice = "Post successfully created"
#
- # 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.
+ # This example places a string in the flash. And of course, you can put as many as you like at a time too. If you want to pass
+ # non-primitive types, you will have to handle that in your application. Example: To show messages with links, you will have to
+ # use sanitize helper.
+ #
+ # Just remember: They'll be gone by the time the next action has been performed.
#
# See docs on the FlashHash class for more details about the flash.
class Flash
@@ -50,13 +55,14 @@ module ActionDispatch
end
def []=(k, v)
+ k = k.to_s
@flash[k] = v
@flash.discard(k)
v
end
def [](k)
- @flash[k]
+ @flash[k.to_s]
end
# Convenience accessor for <tt>flash.now[:alert]=</tt>.
@@ -73,27 +79,36 @@ module ActionDispatch
class FlashHash
include Enumerable
- def self.from_session_value(value)
- flash = case value
- when FlashHash # Rails 3.1, 3.2
- new(value.instance_variable_get(:@flashes), value.instance_variable_get(:@used))
- when Hash # Rails 4.0
- new(value['flashes'], value['discard'])
- else
- new
- end
-
- flash.tap(&:sweep)
+ def self.from_session_value(value) #:nodoc:
+ case value
+ when FlashHash # Rails 3.1, 3.2
+ flashes = value.instance_variable_get(:@flashes)
+ if discard = value.instance_variable_get(:@used)
+ flashes.except!(*discard)
+ end
+ new(flashes, flashes.keys)
+ when Hash # Rails 4.0
+ flashes = value['flashes']
+ if discard = value['discard']
+ flashes.except!(*discard)
+ end
+ new(flashes, flashes.keys)
+ else
+ new
+ end
end
- def to_session_value
- return nil if empty?
- {'discard' => @discard.to_a, 'flashes' => @flashes}
+ # Builds a hash containing the flashes to keep for the next request.
+ # If there are none to keep, returns nil.
+ def to_session_value #:nodoc:
+ flashes_to_keep = @flashes.except(*@discard)
+ return nil if flashes_to_keep.empty?
+ {'flashes' => flashes_to_keep}
end
def initialize(flashes = {}, discard = []) #:nodoc:
- @discard = Set.new(discard)
- @flashes = flashes
+ @discard = Set.new(stringify_array(discard))
+ @flashes = flashes.stringify_keys
@now = nil
end
@@ -106,17 +121,18 @@ module ActionDispatch
end
def []=(k, v)
+ k = k.to_s
@discard.delete k
@flashes[k] = v
end
def [](k)
- @flashes[k]
+ @flashes[k.to_s]
end
def update(h) #:nodoc:
- @discard.subtract h.keys
- @flashes.update h
+ @discard.subtract stringify_array(h.keys)
+ @flashes.update h.stringify_keys
self
end
@@ -125,10 +141,11 @@ module ActionDispatch
end
def key?(name)
- @flashes.key? name
+ @flashes.key? name.to_s
end
def delete(key)
+ key = key.to_s
@discard.delete key
@flashes.delete key
self
@@ -155,7 +172,7 @@ module ActionDispatch
def replace(h) #:nodoc:
@discard.clear
- @flashes.replace h
+ @flashes.replace h.stringify_keys
self
end
@@ -186,6 +203,7 @@ module ActionDispatch
# flash.keep # keeps the entire flash
# flash.keep(:notice) # keeps only the "notice" entry, the rest of the flash is discarded
def keep(k = nil)
+ k = k.to_s if k
@discard.subtract Array(k || keys)
k ? self[k] : self
end
@@ -195,6 +213,7 @@ module ActionDispatch
# 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
def discard(k = nil)
+ k = k.to_s if k
@discard.merge Array(k || keys)
k ? self[k] : self
end
@@ -231,6 +250,12 @@ module ActionDispatch
def now_is_loaded?
@now
end
+
+ def stringify_array(array)
+ array.map do |item|
+ item.kind_of?(Symbol) ? item.to_s : item
+ end
+ end
end
def initialize(app)