So, given a sessionID, I have need to read and write the session stored
information 'manually', from _outside_ an actual Rails
request/controller.
Readers, I know your first response may be to tell me I don't really
want to do that. Trust me though, I really do, it makes sense for me in
my case.
I know this wouldn't work if you're using the new cookie session storage
mechanism. But if you're using a server-side session storage mechanism,
I'm thinking there must be some reasonable way to do this. But I'm
having trouble figuring it out.
I've tried looking through the rails source code to see how Rails reads
and write session, but I'm having trouble finding the relevant code. I
also figured, gee, since Rails allows pluggable session storage
architecture, there must be an abstract description of what a session
store must implement, and how to access it, and that might help me --
but I couldn't find that either.
Anyone have any ideas or tips? I'd like a
session-storage-implementation-agnostic (assuming it's a server-side
method of storage) way to read and write the session hash from outside a
Rails controller.
So, given a sessionID, I have need to read and write the session
stored
information 'manually', from _outside_ an actual Rails
request/controller.
Readers, I know your first response may be to tell me I don't really
want to do that. Trust me though, I really do, it makes sense for me
in
my case.
I know this wouldn't work if you're using the new cookie session
storage
mechanism. But if you're using a server-side session storage
mechanism,
I'm thinking there must be some reasonable way to do this. But I'm
having trouble figuring it out.
I've tried looking through the rails source code to see how Rails
reads
and write session, but I'm having trouble finding the relevant code. I
also figured, gee, since Rails allows pluggable session storage
architecture, there must be an abstract description of what a session
store must implement, and how to access it, and that might help me --
but I couldn't find that either.
How it is stored is almost all up to the session store - they need to
be able to fetch the data for a given session id and store some data
for a session id.
The details have changed between rails 2.2 and 2.3, in 2.2 it was the
old cgi interface, in 2.3 it's the new rack interface - you'll need to
instantiate the appropriate subclass of ActionController::SessionStore
Frederick Cheung wrote:
> The details have changed between rails 2.2 and 2.3, in 2.2 it was the
> old cgi interface, in 2.3 it's the new rack interface - you'll need to
> instantiate the appropriate subclass of ActionController::SessionStore
This helps, thanks. Trying to look through the source and googling, I
did discover that this changed very much between 2.2 and 2.3, I might
need to write two versions of my code.
But since there is an abstract model for a session store, it must be
possible for me to access the session store and read and write session
info without knowing about the black box internals.
Once I've gotten the appropriate ActionController::SessionStore... what
the heck do I do with it in order to read or write session data?
Unless the specs for how to write a session store have changed in 2.3,
it may be my code doesn't need to be different for 2.3. But if it does,
I can deal with that too.
They did - had to rewrite a lot of that bit of my session store for
2.3
In 2.3 Session stores have to implement a get_session method. The
first argument is just the environment hash that rack gives you -
you'll probably have to fiddle around a bit to workout how much you
have to fake up (maybe nothing at all)
Unless the specs for how to write a session store have changed in
2.3,
it may be my code doesn't need to be different for 2.3. But if it
does,
I can deal with that too.
They did - had to rewrite a lot of that bit of my session store for
2.3
Thanks Fred. It actually looks like this would be fairly
straightforward
in 2.3. This blog post provides some hints:
But my app is not yet working with 2.3 in general, and I'd like it to
work with both. And in pre-2.3, it seems, from looking at the Rails
source, that it would be REALLY tricky to do this.
So now I'm thinking of another option. One would be storing this
information in my own database models, keyed by Rails SessionID. But
once I've done that, I've kind of duplicated the ActiveRecordStore. So
another option would be writing my code to assume that the session
store
is an ActiveRecordStore -- if you make this assumption, instead of
trying to write store-agnostic code, then accessing the info in
pre-2.3
looks to be more do-able. And I could write code that works with
either
pre 2.3 or 2.3.
If you assume ActiveRecord store it's pretty easy. find the row with
the right session id, data is right there.
the pre 2.2 way should work way back to rails 1.1, and possibly even
further back.
Huh, then I might as well do it the actual legit way, and I guess I can
now easily do this in a storage-agnostic manner for both pre 2.2 and
2.2. Nice, thanks for supplying that sample code Fred, after a couple
hours looking through the Rails source I wasn't any closer to figuring
it out for myself.
Ah, but I guess now I have your sample code to _read_ a session. Do you
have any similar magic code to write it back out to the store? I guess I
can probably figure it out for myself now that I know the magic way to
fake a cgi session.
Ah, but I guess now I have your sample code to _read_ a session. Do you
have any similar magic code to write it back out to the store? I guess I
can probably figure it out for myself now that I know the magic way to
fake a cgi session.
Ha, I've made it work! Now I just need to do it for rails 2.3 too, to
have it both ways.
But here's the rails pre-2.3 version. Thanks Fred!
Struct.new('FakeSession', :session_id)
# Craziness to restore a session in Rails pre 2.2. Will most
likely
# need to be changed for Rails 2.2.
Okay, pre-Rails-2.2, if you want to fake a session and you want to have
it work to create a new session with that ID even if one doesn't
currently exist, and you sometimes use an ActiveRecord session store
(phew), then instead of simply using a Struct to create a duck-typed
fake session, you need something that will implement new_session too,
still using the same session_id.
class FakeSession
attr_accessor :session_id
def initialize(a_session_id)
self.session_id = a_session_id
end
def new_session
return self.session_id
end
end