views:

145

answers:

1

I'm using the Rails session to store a cookie_jar I get from Mechanize. This lets me call a webservice and maintain the cookies it sends back.

The class takes a session in it's constructor, so I'm passing in the Rails session. Then, when I call the service, I load the cookie_jar (if I have one) like:

agent =  WWW::Mechanize.new
agent.cookie_jar = YAML.load(@session[COOKIE_JAR]) if @session.has_key? COOKIE_JAR

Once I'm done making the call, I store the cookie_jar again like:

@session[COOKIE_JAR] = agent.cookie_jar.to_yaml

While I'd love to just store the "agent", it can't be serialized (and therefore can't go in the session). Here's the funky part: if I call "session.inspect" in my classes constructor (or anytime before checking if the session has the key I'm looking for), everything works fine. Remove the call to "session.inspect" and it doesn't work anymore.

Anyone know why the Rails session behaves this way?

+1  A: 

Try something like this instead:

cj = @session[COOKIE_JAR]
agent.cookie_jar = YAML.load(cj) unless cj.nil?

You may have defeated some rails meta-programming magic by not insisting that it give you an actual string. Sessions are Hash-like objects but not really a Hash.

Update: looking at API docs with source, it's not metaprogramming but just plain logic:

    # File actionpack/lib/action_controller/session/abstract_store.rb, line 27
27:         def [](key)
28:           load! unless @loaded
29:           super
30:         end

SessionHash is derived from Hash but only a few methods get the lazy load wrapper, and has_key? is not one of them.

DigitalRoss