将 Rails 2.0.2 升级到 2.3.5(甚至 2.1.0)后如何修复 Stack Overflow =>在 ActiveRecord::SessionStore 中

发布于 2024-08-22 10:19:52 字数 3152 浏览 4 评论 0原文

好的,我们正在将客户的旧代码从 2.0.2 升级到最新的 Rails。大多数基础知识都很容易修复,但我无法进入管理屏幕。每次我们点击“current_user”时,我们都会收到“堆栈级别太深”错误。

我深入研究了代码(阅读:随机地进行了大量的修改),最终将其范围缩小到 ActiveRecord::Session 存储。

该代码在包含“session[:user]”的行上出现。

当我假脱机脚本/控制台时,我可以使用以下行复制堆栈溢出:

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

stacktrace to follow。

为了确保这不是一些奇怪的不兼容性,我炸掉了数据库中的会话表并使用 rake db:sessions:create 重新加载,并且它仍然在那条线上爆炸。

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:in `field_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:in `write_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:in `send'
 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:in `each'
 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:in `initialize'
 from (irb):10:in `new'

我进入 active_record 并放入大量的 put 行。这是一个简短的版本,最后两行不断重复,显然是堆栈溢出...但是为什么 column_for_attribute(session_id) 会导致溢出?

"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"

注意:我们还尝试升级到 2.1.0 并发生相同的错误(当尝试登录时 - 显然会话类在其间更改了名称,因此 scipt/console 问题取决于类名)。这次它无休止地尝试“id”而不是“session_id”。

当前的environment.rb会话设置(对于2.1.0版本)如下:

# 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" } 

如果我将其恢复到v2.0.2,它会再次工作。

所以我想问题是:v 2.0.2 和 2.1.0 之间的 ActiveRecord Session 发生了什么变化以及如何使其工作?

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:in `field_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:in `write_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:in `send'
 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:in `each'
 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:in `initialize'
 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

他夏了夏天 2024-08-29 10:19:52

好吧,看起来问题是旧的反向端口/猴子补丁。在插件目录中,我们有一个“脏”功能的向后移植 - 我猜它一定是在 Rails 2.1.0 中出现的。我所知道的是,删除该插件似乎已经使“堆栈级别太深”问题消失了(目前)。 :)

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). :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文