原创作者: hideto
阅读:1830次
评论:0条
更新时间:2011-05-26
我们知道Rails默认使用file来存储session数据,放在tmp\sessions目录下
其实我们还可以使用数据库、drb_server、mem_cache甚至内存来存储session数据
方法就是更改environment.rb:
当然使用数据库存储session数据时要先创建数据库表
这在以前的Rails良药系列文章中也提到了
Rails的session管理的源代码文件为session_management.rb:
alias_method_chain对process和process_cleanup方法加上session_management_support
我们在看action_controller/base.rb文件时知道process方法是action调用的入口,而process_cleanup是action调用结束时调用的
而@_session变量也是在base.rb里定义的:
我们可以在controller里调用session这个类方法来指定使用session的范围:
看看active_record_store.rb中的一段代码:
active_record_store是使用数据库保存session,里面定义了create_table!方法以及update/delete/close等与数据库@session相关的操作
而mem_cache_store的update/delete/close等方法的实现则是对@cache的操作,drb_store则是对DRbObject的操作,不同的方式有不同的实现
其实我们还可以使用数据库、drb_server、mem_cache甚至内存来存储session数据
方法就是更改environment.rb:
config.action_controller.session_store = :active_record_store || :drb_store || :mem_cache_store || :memory_store
当然使用数据库存储session数据时要先创建数据库表
rake db:sessions:create
这在以前的Rails良药系列文章中也提到了
Rails的session管理的源代码文件为session_management.rb:
require 'action_controller/session/drb_store' require 'action_controller/session/mem_cache_store' if Object.const_defined?(:ActiveRecord) require 'action_controller/session/active_record_store' end module ActionController module SessionManagement def self.included(base) base.extend(ClassMethods) base.send :alias_method_chain, :process, :session_management_support base.send :alias_method_chain, :process_cleanup, :session_management_support end module ClassMethods def session_store=(store) ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:database_manager] = store.is_a?(Symbol) ? CGI::Session.const_get(store == :drb_store ? "DRbStore" : store.to_s.camelize) : store end def session_store ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:database_manager] end def session_options ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS end def session(*args) options = Hash === args.last ? args.pop : {} options[:disabled] = true if !args.empty? options[: only] = [*options[: only]].map { |o| o.to_s } if options[: only] options[:except] = [*options[:except]].map { |o| o.to_s } if options[:except] if options[: only] && options[:except] raise ArgumentError, "only one of either : only or :except are allowed" end write_inheritable_array("session_options", [options]) end def session_options_for(request, action) #:nodoc: if (session_options = cached_session_options).empty? {} else options = {} action = action.to_s session_options.each do |opts| next if opts[:if] && !opts[:if].call(request) if opts[: only] && opts[: only].include?(action) options.merge!(opts) elsif opts[:except] && !opts[:except].include?(action) options.merge!(opts) elsif !opts[: only] && !opts[:except] options.merge!(opts) end end if options.empty? then options else options.delete : only options.delete :except options.delete :if options[:disabled] ? false : options end end end end def process_with_session_management_support(request, response, method = :perform_action, *arguments) #:nodoc: set_session_options(request) process_without_session_management_support(request, response, method, *arguments) end private def set_session_options(request) request.session_options = self.class.session_options_for(request, request.parameters["action"] || "index") end def process_cleanup_with_session_management_support clear_persistent_model_associations process_cleanup_without_session_management_support end def clear_persistent_model_associations #:doc: if defined?(@_session) && @_session.respond_to?(:data) session_data = @_session.data if session_data && session_data.respond_to?(:each_value) session_data.each_value do |obj| obj.clear_association_cache if obj.respond_to?(:clear_association_cache) end end end end end end
alias_method_chain对process和process_cleanup方法加上session_management_support
我们在看action_controller/base.rb文件时知道process方法是action调用的入口,而process_cleanup是action调用结束时调用的
而@_session变量也是在base.rb里定义的:
@_response = response @_response.session = request.session @_session = @_response.session
我们可以在controller里调用session这个类方法来指定使用session的范围:
# turn off session management for all actions. session : off # turn off session management for all actions _except_ foo and bar. session : off, :except => %w(foo bar) # turn off session management for only the foo and bar actions. session : off, : only => %w(foo bar) # the session will only work over HTTPS, but only for the foo action session : only => :foo, :session_secure => true # the session will only be disabled for 'foo', and only if it is requested as a web service session : off, : only => :foo, :if => Proc.new { |req| req.parameters[:ws] }
看看active_record_store.rb中的一段代码:
class CGI class Session class ActiveRecordStore class Session < ActiveRecord::Base cattr_accessor :data_column_name self.data_column_name = 'data' class << self def create_table! connection.execute <<-end_sql CREATE TABLE #{table_name} ( id INTEGER PRIMARY KEY, #{connection.quote_column_name('session_id')} TEXT UNIQUE, #{connection.quote_column_name(@@data_column_name)} TEXT(255) ) end_sql end def drop_table! connection.execute "DROP TABLE #{table_name}" end end end cattr_accessor :session_class self.session_class = Session def initialize(session, option = nil) session_id = session.session_id unless @session = ActiveRecord::Base.silence { @@session_class.find_by_session_id(session_id) } unless session.new_session raise CGI::Session::NoSession, 'uninitialized session' end @session = @@session_class.new(:session_id => session_id, :data => {}) end end def update if @session ActiveRecord::Base.silence { @session.save } end end def close if @session update @session = nil end end def delete if @session ActiveRecord::Base.silence { @session.destroy } @session = nil end end end end end
active_record_store是使用数据库保存session,里面定义了create_table!方法以及update/delete/close等与数据库@session相关的操作
而mem_cache_store的update/delete/close等方法的实现则是对@cache的操作,drb_store则是对DRbObject的操作,不同的方式有不同的实现
评论 共 0 条 请登录后发表评论