Class: CGI::Session::ActiveRecordStore

Inherits:
Object
  • Object
show all
Defined in:
lib/action_controller/session/active_record_store.rb

Overview

A session store backed by an Active Record class. A default class is provided, but any object duck-typing to an Active Record Session class with text session_id and data attributes is sufficient.

The default assumes a sessions tables with columns:

+id+ (numeric primary key),
+session_id+ (text, or longtext if your session data exceeds 65K), and
+data+ (text or longtext; careful if your session data exceeds 65KB).

The session_id column should always be indexed for speedy lookups. Session data is marshaled to the data column in Base64 format. If the data you write is larger than the column's size limit, ActionController::SessionOverflowError will be raised.

You may configure the table name, primary key, and data column. For example, at the end of config/environment.rb:

CGI::Session::ActiveRecordStore::Session.table_name = 'legacy_session_table'
CGI::Session::ActiveRecordStore::Session.primary_key = 'session_id'
CGI::Session::ActiveRecordStore::Session.data_column_name = 'legacy_session_data'

Note that setting the primary key to the session_id frees you from having a separate id column if you don't want it. However, you must set session.model.id = session.session_id by hand! A before_filter on ApplicationController is a good place.

Since the default class is a simple Active Record, you get timestamps for free if you add created_at and updated_at datetime columns to the sessions table, making periodic session expiration a snap.

You may provide your own session class implementation, whether a feature-packed Active Record or a bare-metal high-performance SQL store, by setting

+CGI::Session::ActiveRecordStore.session_class = MySessionClass+

You must implement these methods:

self.find_by_session_id(session_id)
initialize(hash_of_session_id_and_data)
attr_reader :session_id
attr_accessor :data
save
destroy

The example SqlBypass class is a generic SQL session store. You may use it as a basis for high-performance database-specific stores.

Defined Under Namespace

Classes: Session, SqlBypass

Instance Method Summary collapse

Constructor Details

#initialize(session, option = nil) ⇒ ActiveRecordStore

Find or instantiate a session given a CGI::Session.


279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/action_controller/session/active_record_store.rb', line 279

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 => {})
    # session saving can be lazy again, because of improved component implementation
    # therefore next line gets commented out:
    # @session.save
  end
end

Instance Method Details

#closeObject

Save and close the session store.


312
313
314
315
316
317
# File 'lib/action_controller/session/active_record_store.rb', line 312

def close
  if @session
    update
    @session = nil
  end
end

#deleteObject

Delete and close the session store.


320
321
322
323
324
325
# File 'lib/action_controller/session/active_record_store.rb', line 320

def delete
  if @session
    ActiveRecord::Base.silence { @session.destroy }
    @session = nil
  end
end

#modelObject

Access the underlying session model.


293
294
295
# File 'lib/action_controller/session/active_record_store.rb', line 293

def model
  @session
end

#restoreObject

Restore session state. The session model handles unmarshaling.


298
299
300
301
302
# File 'lib/action_controller/session/active_record_store.rb', line 298

def restore
  if @session
    @session.data
  end
end

#updateObject

Save session store.


305
306
307
308
309
# File 'lib/action_controller/session/active_record_store.rb', line 305

def update
  if @session
    ActiveRecord::Base.silence { @session.save }
  end
end