Created
February 28, 2011 17:06
-
-
Save jimweirich/847634 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This is a fragment of code from action_controller/request.rb that handles sessions. | |
| # (this is Rails 2.3.11 if that matters). | |
| # It is obvious from the first method that a session is expected to be a hash. | |
| def session | |
| @env['rack.session'] ||= {} | |
| end | |
| def session=(session) #:nodoc: | |
| @env['rack.session'] = session | |
| end | |
| # But, if session is a hash, what is "session.destroy" expected to do? | |
| # I'm confused. | |
| def reset_session | |
| session.destroy if session | |
| self.session = {} | |
| end | |
| # We are actually hitting the session.destroy line when session is a normal looking hash. | |
| # I don't understand how this code is even correct. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The rails session is not expected to be an ActiveRecord::Base object. Even when the session is ActiveRecord based, we have an object that wraps an instance of ActiveRecord. So, what is happening?
Rack initializes the session as a hash but it is later replaced by a SessionHash object (which responds to destroy) in the session middleware:
https://github.com/rails/rails/blob/2-3-stable/actionpack/lib/action_controller/session/abstract_store.rb#L208-211
After you reset the session, it sets a hash back. The obvious bug here is that if you call reset_session twice, it will raise an error. It has been fixed in Rails 3-0-stable and master (but it seems it was not backported):
https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/request.rb#L220-224
The session middleware explicitly checks if the session is a hash, and, if so, it serializes it completely back. When the SessionHash object is in the session, it tries to be a bit smarter and just serializes it back if something was written and so on.