The application can behave differently based on the request URL by presenting a diferent 'site' experience to the end-user, who may also choose from the locales (language presentations) that the site supports.The Session manages this: it's a PORO plus some Trailblazer operations. It keeps state for the current request including current user, the Rails session and site and locale selections. It's established with a Session::Create
operation before processing a request.
The Session does not persist across requests, except for data placed in its persistent store
, for which the Rails session is used (but another Hash-like object could be used instead).
The Session is established in the ApplicationController:
before_action do
Session::Create.reject(params.merge(store: session, host: request.host,
preferred_locales: get_preferred_locales_from_http_request)) do |op|
redirect_to '/404.html'
end
end
The additional parameters that the Session requires are merged into the params
hash. If the requested site
isn't recognised then a 404 is returned. Note the use of reject
instead of run
to invert the purpose of the block.
The actual Session
is just a PORO with some class instance variables that the Session::Create
operation initialises; its state is indeterminate before this is done (note: it may leak from a prior request if not initialised!). It is essentially like this:
class Session
class << self
attr_reader :site
attr_reader :user
attr_reader :store
end
The Session::Create
operation is like this:
class Create < Trailblazer::Operation
def process(params)
Session.store = params[:store]
select_site(params[:host]) &&
select_locale(params[:locale], params[:preferred_locales])
Session.user = User.find_by_id(Session.store[:user_id])
end
Private methods do the setup work and return invalid!
if they wish to invalidate the session (e.g. unrecognised site
)