A barebones session store which duck-types with the default session store but bypasses Active Record and issues SQL directly. This is an example session model class meant as a basis for your own classes.
The database connection, table name, and session id and data columns are configurable class attributes. Marshaling and unmarshaling are implemented as class methods that you may override. By default, marshaling data is +Base64.encode64(Marshal.dump(data))+ and unmarshaling data is +Marshal.load(Base64.decode64(data))+.
This marshaling behavior is intended to store the widest range of binary
session data in a text
column. For higher performance, store
in a blob
column instead and forgo the Base64 encoding.
- C
- D
- F
- L
- M
- N
- S
- U
[W] | data | |
[R] | session_id |
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 181 def connection @@connection ||= ActiveRecord::Base.connection end
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 195 def create_table! @@connection.execute " CREATE TABLE #{table_name} ( id INTEGER PRIMARY KEY, #{@@connection.quote_column_name(session_id_column)} TEXT UNIQUE, #{@@connection.quote_column_name(data_column)} TEXT ) " end
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 205 def drop_table! @@connection.execute "DROP TABLE #{table_name}" end
Look up a session by id and unmarshal its data if found.
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 186 def find_by_session_id(session_id) if record = @@connection.select_one("SELECT * FROM #{@@table_name} WHERE #{@@session_id_column}=#{@@connection.quote(session_id)}") new(:session_id => session_id, :marshaled_data => record['data']) end end
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 192 def marshal(data) Base64.encode64(Marshal.dump(data)) if data end
Look for normal and marshaled data, self.find_by_session_id’s way of telling us to postpone unmarshaling until the data is requested. We need to handle a normal data attribute in case of a new record.
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 216 def initialize(attributes) @session_id, @data, @marshaled_data = attributes[:session_id], attributes[:data], attributes[:marshaled_data] @new_record = @marshaled_data.nil? end
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 193 def unmarshal(data) Marshal.load(Base64.decode64(data)) if data end
Lazy-unmarshal session state.
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 226 def data unless @data if @marshaled_data @data, @marshaled_data = self.class.unmarshal(@marshaled_data) || {}, nil else @data = {} end end @data end
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 264 def destroy unless @new_record @@connection.delete " DELETE FROM #{@@table_name} WHERE #{@@connection.quote_column_name(@@session_id_column)}=#{@@connection.quote(session_id)} ", 'Destroy session' end end
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 237 def loaded? !! @data end
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 221 def new_record? @new_record end
Source: show
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 241 def save return false if !loaded? marshaled_data = self.class.marshal(data) if @new_record @new_record = false @@connection.update " INSERT INTO #{@@table_name} ( #{@@connection.quote_column_name(@@session_id_column)}, #{@@connection.quote_column_name(@@data_column)} ) VALUES ( #{@@connection.quote(session_id)}, #{@@connection.quote(marshaled_data)} ) ", 'Create session' else @@connection.update " UPDATE #{@@table_name} SET #{@@connection.quote_column_name(@@data_column)}=#{@@connection.quote(marshaled_data)} WHERE #{@@connection.quote_column_name(@@session_id_column)}=#{@@connection.quote(session_id)} ", 'Update session' end end