~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/actionpack/lib/action_controller/flash.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
module ActionController #:nodoc:
2
 
  # The flash provides a way to pass temporary objects between actions. Anything you place in the flash will be exposed
3
 
  # to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create
4
 
  # action that sets <tt>flash[:notice] = "Successfully created"</tt> before redirecting to a display action that can
5
 
  # then expose the flash to its template. Actually, that exposure is automatically done. Example:
6
 
  #
7
 
  #   class PostsController < ActionController::Base
8
 
  #     def create
9
 
  #       # save post
10
 
  #       flash[:notice] = "Successfully created post"
11
 
  #       redirect_to posts_path(@post)
12
 
  #     end
13
 
  #
14
 
  #     def show
15
 
  #       # doesn't need to assign the flash notice to the template, that's done automatically
16
 
  #     end
17
 
  #   end
18
 
  #
19
 
  #   show.html.erb
20
 
  #     <% if flash[:notice] %>
21
 
  #       <div class="notice"><%= flash[:notice] %></div>
22
 
  #     <% end %>
23
 
  #
24
 
  # This example just places a string in the flash, but you can put any object in there. And of course, you can put as
25
 
  # many as you like at a time too. Just remember: They'll be gone by the time the next action has been performed.
26
 
  #
27
 
  # See docs on the FlashHash class for more details about the flash.
28
 
  module Flash
29
 
    def self.included(base)
30
 
      base.class_eval do
31
 
        include InstanceMethods
32
 
        alias_method_chain :perform_action, :flash
33
 
        alias_method_chain :reset_session,  :flash
34
 
      end
35
 
    end
36
 
 
37
 
    class FlashNow #:nodoc:
38
 
      def initialize(flash)
39
 
        @flash = flash
40
 
      end
41
 
 
42
 
      def []=(k, v)
43
 
        @flash[k] = v
44
 
        @flash.discard(k)
45
 
        v
46
 
      end
47
 
 
48
 
      def [](k)
49
 
        @flash[k]
50
 
      end
51
 
    end
52
 
 
53
 
    class FlashHash < Hash
54
 
      def initialize #:nodoc:
55
 
        super
56
 
        @used = {}
57
 
      end
58
 
 
59
 
      def []=(k, v) #:nodoc:
60
 
        keep(k)
61
 
        super
62
 
      end
63
 
 
64
 
      def update(h) #:nodoc:
65
 
        h.keys.each { |k| keep(k) }
66
 
        super
67
 
      end
68
 
 
69
 
      alias :merge! :update
70
 
 
71
 
      def replace(h) #:nodoc:
72
 
        @used = {}
73
 
        super
74
 
      end
75
 
 
76
 
      # Sets a flash that will not be available to the next action, only to the current.
77
 
      #
78
 
      #     flash.now[:message] = "Hello current action"
79
 
      #
80
 
      # This method enables you to use the flash as a central messaging system in your app.
81
 
      # When you need to pass an object to the next action, you use the standard flash assign (<tt>[]=</tt>).
82
 
      # When you need to pass an object to the current action, you use <tt>now</tt>, and your object will
83
 
      # vanish when the current action is done.
84
 
      #
85
 
      # Entries set via <tt>now</tt> are accessed the same way as standard entries: <tt>flash['my-key']</tt>.
86
 
      def now
87
 
        FlashNow.new(self)
88
 
      end
89
 
 
90
 
      # Keeps either the entire current flash or a specific flash entry available for the next action:
91
 
      #
92
 
      #    flash.keep            # keeps the entire flash
93
 
      #    flash.keep(:notice)   # keeps only the "notice" entry, the rest of the flash is discarded
94
 
      def keep(k = nil)
95
 
        use(k, false)
96
 
      end
97
 
 
98
 
      # Marks the entire flash or a single flash entry to be discarded by the end of the current action:
99
 
      #
100
 
      #     flash.discard              # discard the entire flash at the end of the current action
101
 
      #     flash.discard(:warning)    # discard only the "warning" entry at the end of the current action
102
 
      def discard(k = nil)
103
 
        use(k)
104
 
      end
105
 
 
106
 
      # Mark for removal entries that were kept, and delete unkept ones.
107
 
      #
108
 
      # This method is called automatically by filters, so you generally don't need to care about it.
109
 
      def sweep #:nodoc:
110
 
        keys.each do |k|
111
 
          unless @used[k]
112
 
            use(k)
113
 
          else
114
 
            delete(k)
115
 
            @used.delete(k)
116
 
          end
117
 
        end
118
 
 
119
 
        # clean up after keys that could have been left over by calling reject! or shift on the flash
120
 
        (@used.keys - keys).each{ |k| @used.delete(k) }
121
 
      end
122
 
 
123
 
      def store(session, key = "flash")
124
 
        return if self.empty?
125
 
        session[key] = self
126
 
      end
127
 
 
128
 
      private
129
 
        # Used internally by the <tt>keep</tt> and <tt>discard</tt> methods
130
 
        #     use()               # marks the entire flash as used
131
 
        #     use('msg')          # marks the "msg" entry as used
132
 
        #     use(nil, false)     # marks the entire flash as unused (keeps it around for one more action)
133
 
        #     use('msg', false)   # marks the "msg" entry as unused (keeps it around for one more action)
134
 
        def use(k=nil, v=true)
135
 
          unless k.nil?
136
 
            @used[k] = v
137
 
          else
138
 
            keys.each{ |key| use(key, v) }
139
 
          end
140
 
        end
141
 
    end
142
 
 
143
 
    module InstanceMethods #:nodoc:
144
 
      protected
145
 
        def perform_action_with_flash
146
 
          perform_action_without_flash
147
 
          if defined? @_flash
148
 
            @_flash.store(session)
149
 
            remove_instance_variable(:@_flash)
150
 
          end
151
 
        end
152
 
 
153
 
        def reset_session_with_flash
154
 
          reset_session_without_flash
155
 
          remove_instance_variable(:@_flash) if defined? @_flash
156
 
        end
157
 
 
158
 
        # Access the contents of the flash. Use <tt>flash["notice"]</tt> to
159
 
        # read a notice you put there or <tt>flash["notice"] = "hello"</tt>
160
 
        # to put a new one.
161
 
        def flash #:doc:
162
 
          if !defined?(@_flash)
163
 
            @_flash = session["flash"] || FlashHash.new
164
 
            @_flash.sweep
165
 
          end
166
 
 
167
 
          @_flash
168
 
        end
169
 
    end
170
 
  end
171
 
end