diff options
Diffstat (limited to 'actionpack/lib/action_controller')
-rw-r--r-- | actionpack/lib/action_controller/session/active_record_store.rb | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/actionpack/lib/action_controller/session/active_record_store.rb b/actionpack/lib/action_controller/session/active_record_store.rb index 9e0db037d0..6238b8cbee 100644 --- a/actionpack/lib/action_controller/session/active_record_store.rb +++ b/actionpack/lib/action_controller/session/active_record_store.rb @@ -3,21 +3,25 @@ begin require 'active_record' require 'cgi' require 'cgi/session' +require 'base64' # Contributed by Tim Bates class CGI class Session - # ActiveRecord database based session storage class. + # Active Record database-based session storage class. # # Implements session storage in a database using the ActiveRecord ORM library. Assumes that the database # has a table called +sessions+ with columns +id+ (numeric, primary key), +sessid+ and +data+ (text). - # The session data is stored in the +data+ column in YAML format; the user is responsible for ensuring that - # only data that can be YAMLized is stored in the session. + # The session data is stored in the +data+ column in the binary Marshal format; the user is responsible for ensuring that + # only data that can be Marshaled is stored in the session. + # + # Adding +created_at+ or +updated_at+ datetime columns to the sessions table will enable stamping of the data, which can + # be used to clear out old sessions. + # + # It's highly recommended to have an index on the sessid column to improve performance. class ActiveRecordStore # The ActiveRecord class which corresponds to the database table. class Session < ActiveRecord::Base - serialize :data - # Isn't this class definition beautiful? end # Create a new ActiveRecordStore instance. This constructor is used internally by CGI::Session. @@ -30,8 +34,8 @@ class CGI # This session's ActiveRecord database row will be created if it does not exist, or opened if it does. def initialize(session, option=nil) ActiveRecord::Base.silence do - @session = Session.find_by_sessid(session.session_id) || Session.new("sessid" => session.session_id, "data" => {}) - @data = @session.data + @session = Session.find_by_sessid(session.session_id) || Session.new("sessid" => session.session_id, "data" => marshalize({})) + @data = unmarshalize(@session.data) end end @@ -52,18 +56,27 @@ class CGI # Restore session state from the session's ActiveRecord object. def restore return unless @session - @data = @session.data + @data = unmarshalize(@session.data) end # Save session state in the session's ActiveRecord object. def update return unless @session - ActiveRecord::Base.silence { @session.update_attribute "data", @data } + ActiveRecord::Base.silence { @session.update_attribute "data", marshalize(@data) } end + + private + def unmarshalize(data) + Marshal.load(Base64.decode64(data)) + end + + def marshalize(data) + Base64.encode64(Marshal.dump(data)) + end end #ActiveRecordStore end #Session end #CGI rescue LoadError # Couldn't load Active Record, so don't make this store available -end
\ No newline at end of file +end |