Rails源代码分析(6):ActionController::Flash
来源:互联网 发布:mac虚拟机占内存吗 编辑:程序博客网 时间:2024/04/29 01:01
Flash的作用:
The flash provides a way to pass temporary objects 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。
实际上它是利用session机制来传递对象。
看看代码:
- module Flash
- def self.included(base)
- base.class_eval do
- include InstanceMethods
- alias_method_chain :assign_shortcuts, :flash
- alias_method_chain :reset_session, :flash
- end
- end
- class FlashNow #:nodoc:
- def initialize(flash)
- @flash = flash
- end
- def []=(k, v)
- @flash[k] = v
- @flash.discard(k)
- v
- end
- def [](k)
- @flash[k]
- end
- end
- class FlashHash < Hash
- def initialize #:nodoc:
- super
- @used = {}
- end
- def []=(k, v) #:nodoc:
- keep(k)
- super
- end
- def update(h) #:nodoc:
- h.keys.each { |k| keep(k) }
- super
- end
- alias :merge! :update
- def replace(h) #:nodoc:
- @used = {}
- super
- end
- # Sets a flash that will not be available to the next action, only to the current.
- #
- # flash.now[:message] = "Hello current action"
- #
- # 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
- FlashNow.new(self)
- end
- # Keeps either the entire current flash or a specific flash entry available for the next action:
- #
- # 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)
- use(k, false)
- end
- # Marks the entire flash or a single flash entry to be discarded by the end of the current action:
- #
- # 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)
- use(k)
- end
- # 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:
- keys.each do |k|
- unless @used[k]
- use(k)
- else
- delete(k)
- @used.delete(k)
- end
- end
- # clean up after keys that could have been left over by calling reject! or shift on the flash
- (@used.keys - keys).each{ |k| @used.delete(k) }
- end
- 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)
- def use(k=nil, v=true)
- unless k.nil?
- @used[k] = v
- else
- keys.each{ |key| use(key, v) }
- end
- end
- end
- module InstanceMethods #:nodoc:
- protected
- def reset_session_with_flash
- reset_session_without_flash
- remove_instance_variable(:@_flash)
- flash(:refresh)
- end
- # 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.
- # Note that if sessions are disabled only flash.now will work.
- def flash(refresh = false) #:doc:
- if !defined?(@_flash) || refresh
- @_flash =
- if session.is_a?(Hash)
- # don't put flash in session if disabled
- FlashHash.new
- else
- # otherwise, session is a CGI::Session or a TestSession
- # so make sure it gets retrieved from/saved to session storage after request processing
- session["flash"] ||= FlashHash.new
- end
- end
- @_flash
- end
- private
- def assign_shortcuts_with_flash(request, response) #:nodoc:
- assign_shortcuts_without_flash(request, response)
- flash(:refresh)
- flash.sweep if @_session && !component_request?
- end
- end
- end
FlashNow
FlashHash
FlashNow是FlashHash的包装类,就是为了实现一个机制:
Sets a flash that will not be available to the next action, only to the current.
FlashHash提供了工厂方法生成:
def now
FlashNow.new(self)
end
FlashHash是继承Hash来实现,里面实现的一个关键点就是它用了一个@used类变量,利用use方法来设置
def use(k=nil, v=true)
unless k.nil?
@used[k] = v
else
keys.each{ |key| use(key, v) }
end
end
实现跨方法调用的关键就是:
FlashHash类
def []=(k, v)
keep(k)
super
end
keep将设置为没有使用
def keep(k = nil)
use(k, false)
end
如果还没有used的设置为use,如果used的删除这个值
效果等于把用过的值删掉,没有用过的标记为用过的
def sweep #:nodoc:
keys.each do |k|
unless @used[k]
use(k)
else
delete(k)
@used.delete(k)
end
end
将used的keys和这个hash的keys同步
(@used.keys - keys).each{ |k| @used.delete(k) }
end
alias_method_chain :assign_shortcuts, :flash
alias_method_chain :reset_session, :flash
这个实际上先重命名
原assign_shortcuts => assign_shortcuts_without_flash
原reset_session => reset_session_without_flash
然后原方法调用就变为调用:
def reset_session_with_flash
reset_session_without_flash
remove_instance_variable(:@_flash)
flash(:refresh)
end
def assign_shortcuts_with_flash(request, response) #:nodoc:
assign_shortcuts_without_flash(request, response)
flash(:refresh)
flash.sweep if @_session && !component_request?
end
flash.sweep就是清除了
- Rails源代码分析(6):ActionController::Flash
- Rails源代码分析(22):ActionController::Caching(6) Sweeping
- Rails源代码分析(35):ActionController::Routing(6) Segment
- Rails源代码分析(5):ActionController概览
- Rails源代码分析(12):ActionController::Benchmarking
- Rails源代码分析(13):ActionController::Rescue
- Rails源代码分析(14):ActionController::MimeResponds
- Rails源代码分析(15):ActionController::Helpers
- Rails源代码分析(16):ActionController::Cookies
- Rails源代码分析(23):ActionController::Verification
- Rails源代码分析(24):ActionController::Streaming
- Rails源代码分析(25):ActionController::SessionManagement
- Rails源代码分析(27):ActionController::RecordIdentifier
- Rails源代码分析(28):ActionController::RequestForgeryProtection
- Rails源代码分析(7):ActionController::Filter(1)
- Rails源代码分析(8):ActionController::Filter(2)
- Rails源代码分析(9):ActionController::Filter(3)
- Rails源代码分析(10):ActionController::Layout(1)
- Windows内核对象
- Delphi 命名 经验
- javascript中apply使用方法小议
- ireport社区
- 3x+1问题
- Rails源代码分析(6):ActionController::Flash
- 1.singleton模式的的两种实现方式
- How "Copy File" works in 'View Output" screen in Oracle Apps
- js截断长文章
- 信息追凶---DB2 PureXML 技术在刑侦破案的应用
- System.getProperty()参数大全
- Occlusion Culling Algorithms
- 面试例题1
- Struts 2中的OGNL