This project is archived and is in readonly mode.

#2441 ✓stale
Adam Sindelar

ActiveRecord::SessionStore breaks with custom model

Reported by Adam Sindelar | April 7th, 2009 @ 03:34 PM | in 3.x

When using ActiveRecord::SessionStore for session management with a custom model class (set using ActiveRecord::SessionStore.session_class=), the custom model fails to work if it inherits from ActiveRecord::Base (which is the usual case).

The concrete problem seems to be caused by the fact that some class variables of ActiveRecord::Base are inexplicably set to nil sometime after the class is assigned to SessionStore.session_class. The two cases where I know for certain that this happens are Base.skip_time_zone_conversion_for_attributes and Base.default_scoping.

I have isolated the issue to how Rails handles application classes between requests in development environment, and I believe the process, in which things break is roughly this:

  1. Server boots
  2. Application classes are loaded
  3. initializers/session_store.rb is loaded and a model class is assigned into ActiveRecord's class variable
  4. Rails throws out application classes after a request is completed (because of config.cache_classes = false); meanwhile, ActiveRecord still maintains reference to a class that's no longer supposed to exist, and was crippled by the unloading mechanism. Somehow, in this stage, that model's class variables are set to nil for some reason.
  5. Application classes are reloaded, but the new class objects are different from the one retained in ActiveRecord.

Based on my hypothesis, I devised a quick fix for this:

class ApplicationController < ActionController::Base before_filter {|c| ActiveRecord::SessionStore.session_class = UserSession}

...which seems to work. I'm not familiar with the unloading mechanism in Rails, and so I'm not sure how to fix this, but I would say it's relatively critical, since it basically makes the ActiveRecord store useless for all but the simplest cases.

Comments and changes to this ticket

  • Sai Emrys

    Sai Emrys October 20th, 2009 @ 10:19 AM

    I had the same error, and the same fix. I was previously setting session_class= in my session_store_keys initializer, right after the :active_record_store declaration, which worked fine.

    This occurred when upgrading Rails from 2.3.2 to 2.3.4; my suspicion is that it has to do with 2.3.3.

    After the upgrade, the first load worked fine and the second punted the "can't dup NilClass" error.

    The "unloadable" trick mentioned in did NOT work to resolve this issue, nor was it affected by development vs production mode; the above before_filter DID.

    I'm curious however whether this fix comes at a performance cost... is it incurring extra class reloading penalty that would otherwise only be had on first load?

    If yes, that kinda sucks.

  • Jeremy Kemper

    Jeremy Kemper May 4th, 2010 @ 06:48 PM

    • Milestone changed from 2.x to 3.x
  • Santiago Pastorino

    Santiago Pastorino February 2nd, 2011 @ 04:39 PM

    • State changed from “new” to “open”
    • Importance changed from “” to “”

    This issue has been automatically marked as stale because it has not been commented on for at least three months.

    The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.

    Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.

  • Santiago Pastorino

    Santiago Pastorino February 2nd, 2011 @ 04:39 PM

    • State changed from “open” to “stale”

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href=""></a>

People watching this ticket