Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow ActiveRecordStore.session_class to be evaluated lazily #208

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions lib/action_dispatch/session/active_record_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ module Session
# feature-packed Active Record or a bare-metal high-performance SQL
# store, by setting
#
# ActionDispatch::Session::ActiveRecordStore.session_class = MySessionClass
# ActionDispatch::Session::ActiveRecordStore.session_class = "MySessionClass"
#
# You must implement these methods:
# The class may optionally be passed as a string or proc to prevent autoloading
# code early. You must implement these methods:
#
# self.find_by_session_id(session_id)
# initialize(hash_of_session_id_and_data, options_hash = {})
Expand All @@ -53,13 +54,33 @@ module Session
# The example SqlBypass class is a generic SQL session store. You may
# use it as a basis for high-performance database-specific stores.
class ActiveRecordStore < ActionDispatch::Session::AbstractSecureStore
# The class used for session storage. Defaults to
# ActiveRecord::SessionStore::Session
class_attribute :session_class
class << self
# The class used for session storage. Defaults to
# ActiveRecord::SessionStore::Session
def session_class
@session_class_instance ||= case @session_class
when Proc
@session_class.call
when String
@session_class.constantize
else
@session_class
end
end

def session_class=(session_class)
@session_class_instance = nil
@session_class = session_class
end
end

SESSION_RECORD_KEY = 'rack.session.record'
ENV_SESSION_OPTIONS_KEY = Rack::RACK_SESSION_OPTIONS

def session_class
self.class.session_class
end

private
def get_session(request, sid)
logger.silence do
Expand Down
39 changes: 39 additions & 0 deletions test/session_store_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require "helper"
require "action_dispatch/session/active_record_store"

module ActionDispatch
module Session
class ActiveRecordStoreTest < ActiveSupport::TestCase

class Session < ActiveRecord::SessionStore::Session; end

def test_session_class_as_string
with_session_class("ActionDispatch::Session::ActiveRecordStoreTest::Session") do
assert_equal(Session, ActiveRecordStore.session_class)
end
end

def test_session_class_as_proc
with_session_class(proc { Session }) do
assert_equal(Session, ActiveRecordStore.session_class)
end
end

def test_session_class_as_class
with_session_class(Session) do
assert_equal(Session, ActiveRecordStore.session_class)
end
end

private

def with_session_class(klass)
old_klass = ActiveRecordStore.session_class
ActiveRecordStore.session_class = klass
yield
ensure
ActiveRecordStore.session_class = old_klass
end
end
end
end
Loading