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.

Methods
C
D
F
L
M
N
S
U
Attributes
[W] data
[R] session_id
Class Public methods
connection()
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 181
def connection
  @@connection ||= ActiveRecord::Base.connection
end
create_table!()
# 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
drop_table!()
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 205
def drop_table!
  @@connection.execute "DROP TABLE #{table_name}"
end
find_by_session_id(session_id)

Look up a session by id and unmarshal its data if found.

# 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
marshal(data)
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 192
def marshal(data)   Base64.encode64(Marshal.dump(data)) if data end
new(attributes)

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.

# 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
unmarshal(data)
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 193
def unmarshal(data) Marshal.load(Base64.decode64(data)) if data end
Instance Public methods
data()

Lazy-unmarshal session state.

# 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
destroy()
# 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
loaded?()
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 237
def loaded?
  !! @data
end
new_record?()
# File rails/actionpack/lib/action_controller/session/active_record_store.rb, line 221
def new_record?
  @new_record
end
save()
# 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