Please consider: Session handling too cumbersome and not DRY


#1

Session handling is a bit too cumbersome for my taste in Rails. It seems
to go against the DRY spirit of Rails. Using sessions feels like being
back in the PHP world or in some other lesser system.

So what would you think, if

Short version:

  1. session (or @session) should always refer to an instance of an
    ActiveRecord object Session. It could have special methods mixed in
    automatically by the system, if needed.

  2. It’s bad design to have two different front-ends for data storage,
    the ActiveRecord and the session. So the session data should live in the
    AR model and that specific model could optionally be configured to use
    some other data store. Better to have just one object oriented front-end
    and several back ends, configurable on model by model basis.

Longer version, if I may:

  1. Accessing the session data

We have ActiveRecord which is nice. It’s easy to create model
objects and deal with them. Session, on the other hand, is not
an AR object. (the thing that you can actually end up saving the
YAML encoded data into an AR data store doesn’t change the fact.)

So the session data don’t have proper object oriented structure
like any other AR object in the Rails application do. Instead you
have to manually put arbitrary strings there through a hash,
extend existing AR objects to _dump only the corresponding AR id
or manually make custom objects serializable by hand in order to
save them in a session. Sounds like an unnecessary work to me.

It’s not like you didn’t know what data you’re putting in a
session. Therefore you could as well define the whole session
thing as a model. Then you could naturally reference other AR
objects from the session by using :belongs_to and newcomers would
never have to be explained why storing serialized objects in the
session is a bad idea over and over again. It would all be done
safely and automatically by ActiveRecord. Also you could alter
the session table as much you’d like without breaking older
sessions.

  1. Implementation is also very much not DRY

I think that people are actively making matters worse by inventing
different non-AR data stores just for the sessions. Why are they
doing that?

Well, since the session is not an ActiveRecord by definition,
people have been forced to come up with several alternative storage
methods. I see that the intention is good, making performance
improvements and all that. To my eyes, it’s just bad design.

Instead we should be making alternative backing stores for
the ActiveRecord! In the Session model, you could then define
that this model will use the barebones-on-the-metal-superfast-memcache
backend. Other AR records would use whatever database they were
already using, or maybe some could take advantage of these new
different storage methods. It wouldn’t matter that the
session-optimized AR data stores would be very slow for general
purpose use since you have a choice.

It’s all about making the thing #1 possible, making programming
straightforward, intuitive and consistent even with the sessions.
Also, DRY and the principle of the least surprise apply.

Disclaimer: I’m sorry if this has already been considered for a
future Rails version but at least I didn’t find anything about it.


#2

class MySession < ActiveRecord::Base
has_many …
belongs_to …
validates…

class < self
def current
Thread.current[:session]
end
def current=(s)
Thread.current[:seesion] = s
end
end

instance methods

def …
end
end

class ApplicationController < ActionController::Base
before_filter :setup_my_session

private
def setup_my_session
MySession.current = session[:my_session_id]
end
end

helllo.rhtml
<%= "Hello #{MySession.current.user.name}! %>

This is an extreme example but it follows the principle of storing
object ids in the session and objects the database. You get all the
benefits of ActiveRecord without the downsides of managing complicated
session data.

Aaron