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
N
S
T
Attributes
[W] connection

Use the ActiveRecord::Base#connection by default.

[W] connection_pool

Use the ActiveRecord::Base.connection_pool by default.

[W] data
[R] new_record
[R] new_record?
[R] session_id
Class Public methods
connection()
# File activerecord/lib/active_record/session_store.rb, line 211
def connection
  @connection ||= ActiveRecord::Base.connection
end
connection_pool()
# File activerecord/lib/active_record/session_store.rb, line 215
def connection_pool
  @connection_pool ||= ActiveRecord::Base.connection_pool
end
data_column

The data field defaults to ‘data’.

Also aliased as: data_column_name
# File activerecord/lib/active_record/session_store.rb, line 199
cattr_accessor :data_column
data_column_name
find_by_session_id(session_id)

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

# File activerecord/lib/active_record/session_store.rb, line 220
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
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 activerecord/lib/active_record/session_store.rb, line 237
def initialize(attributes)
  @session_id     = attributes[:session_id]
  @data           = attributes[:data]
  @marshaled_data = attributes[:marshaled_data]
  @new_record     = @marshaled_data.nil?
end
session_id_column

The session id field defaults to ‘#session_id’.

# File activerecord/lib/active_record/session_store.rb, line 193
cattr_accessor :session_id_column
table_name

The table name defaults to ‘sessions’.

# File activerecord/lib/active_record/session_store.rb, line 187
cattr_accessor :table_name
Instance Public methods
data()

Lazy-unmarshal session state.

# File activerecord/lib/active_record/session_store.rb, line 245
def data
  unless @data
    if @marshaled_data
      @data, @marshaled_data = self.class.unmarshal(@marshaled_data) || {}, nil
    else
      @data = {}
    end
  end
  @data
end
destroy()
# File activerecord/lib/active_record/session_store.rb, line 284
      def destroy
        return if @new_record

        connect = connection
        connect.delete "          DELETE FROM #{table_name}
          WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(session_id)}
", 'Destroy session'
      end
loaded?()
# File activerecord/lib/active_record/session_store.rb, line 256
def loaded?
  @data
end
save()
# File activerecord/lib/active_record/session_store.rb, line 260
      def save
        return false unless loaded?
        marshaled_data = self.class.marshal(data)
        connect        = connection

        if @new_record
          @new_record = false
          connect.update "            INSERT INTO #{table_name} (
              #{connect.quote_column_name(session_id_column)},
              #{connect.quote_column_name(data_column)} )
            VALUES (
              #{connect.quote(session_id)},
              #{connect.quote(marshaled_data)} )
", 'Create session'
        else
          connect.update "            UPDATE #{table_name}
            SET #{connect.quote_column_name(data_column)}=#{connect.quote(marshaled_data)}
            WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(session_id)}
", 'Update session'
        end
      end