views:

230

answers:

1

Ok, so we're upgrading a client's legacy code from 2.0.2 to latest rails. Most of the basics were easy to fix, but I can't get to the admin screens. Every time we hit "current_user" we get a "stack level too deep" error.

I've dug deeply into the code (read: flailed around a lot at random) and I've finally narrowed it down to the ActiveRecord::Session store.

The code berks out on the line that includes "session[:user]".

When I spool up script/console I can replicate the stack overflow with the following line:

s = ActiveRecord::SessionStore::Session.new(:session_id => '42', :data => {})

stacktrace to follow.

To make sure it wasn't some weird incompatibility, I blew away the session table in the db and reloaded using rake db:sessions:create and it's still asploding on that line.

SystemStackError: stack level too deep

from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/schema_definitions.rb:68:in type_cast' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/dirty.rb:161:infield_changed?' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/dirty.rb:132:in write_attribute_without_dirty' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/dirty.rb:139:inwrite_attribute' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/attribute_methods.rb:211:in session_id=' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2746:insend' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2746:in attributes=' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2742:ineach' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2742:in attributes=' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2438:ininitialize' from (irb):10:in `new'

I went into active_record and put in heaps of puts lines. Here's a brief version the final two lines are continually repeated and are clearly the stack-overflow... but why does column_for_attribute(session_id) cause an overflow?

"in respond_to? method: session_id="
"in respond_to? session_id= - there are no generated methods. generating..."
"in respond_to? session_id= - methods generated"
"responds to session_id=? y"
"in respond_to? method: session_id="
"in respond_to? session_id= - super is true"
"in read_attribute: session_id about to fetch value"
"fetched attr value: nil"
"read attr: session_id - value nil"
"column for attribute: session_id"
"c_for_a got col hash - accessing for name: session_id"
"column for attribute: session_id"
"c_for_a got col hash - accessing for name: session_id"
"column for attribute: session_id"
"c_for_a got col hash - accessing for name: session_id"
"column for attribute: session_id"
"c_for_a got col hash - accessing for name: session_id"

Note: we also tried upgrading just to 2.1.0 and the same error occurs (when trying to login - obviously the session-class changed names in between so the scipt/console issue depends on the classname). This time it's endlessly trying just "id" instead of "session_id".

Current environment.rb session settings (for the 2.1.0 version) is below:

# Use the database for sessions instead of the file system
# (create the session table with 'rake db:sessions:create')
config.action_controller.session_store = :active_record_store
config.action_controller.session = { :session_key => "_our_session_id",
    :secret=> "some random secret key of your choosing over 30 characters" } 

If I drop it back to v2.0.2 it works again.

So I guess the question is: what changed in the ActiveRecord Session between v 2.0.2 and 2.1.0 and how do I make it work?

+1  A: 

Ok, looks like the problem was an old back-port/monkey-patch. In the plugins directory we had a back-port of the "dirty" functionality - which I'm guessing must've come out in Rails 2.1.0. All I know is that deleting that plugin seems to have made the "stack level too deep" problem go away (for now). :)

Taryn East