堆栈级别到深 Rails 2.3.14 [英] stack level to deep Rails 2.3.14

查看:55
本文介绍了堆栈级别到深 Rails 2.3.14的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为管理框架开发插件,当我在开发模式下启动 webrick 服务器时,出现了一个奇怪的错误(堆栈级别太深).它发生在一个动作(例如 show 动作)开始呈现模板时.不幸的是,我不知道为什么会这样.

故事中的系统堆栈错误#show显示第 5 行引发的 vendor/plugins/stories/app/views/stories/show.rhtml:堆栈级别太深提取的源代码(围绕第 5 行):5: link_to_if_authorized 'aa', {:controller =>"故事", :action =>"索引", :id =>@story.id, :project_id =>@story.project.id}, :title =>l(:view_story), :class =>'图标图标缩小'6: link_to_if_authorized 'bb', {:controller =>"故事", :action =>"编辑", :id =>@story.id, :project_id =>@story.project.id}, :title =>l(:button_edit), :class =>'图标图标编辑'7: link_to 'bb', {:id =>@story.id, :project_id =>@story.project.id}, :confirm =>'真的要删除吗?', :method =>:delete, :class =>'icon icon-del' 如果 User.current.allowed_to?(:delete_stories, @project)RAILS_ROOT:/home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN应用程序跟踪 |框架跟踪 |完整跟踪/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/attribute_methods.rb:248:in method_missing'/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/attribute_methods.rb:249:in method_missing'/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/associations/association_proxy.rb:215:in send'/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/associations/association_proxy.rb:215:in method_missing'/home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN/vendor/plugins/stories/app/views/stories/show.rhtml:5:in _run_rhtml_vendor47plugins47stories47app47views47stories47show46rhtml'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/renderable.rb:34:in send'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/renderable.rb:34:in render'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:306:in with_template'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/renderable.rb:30:in render'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/template.rb:205:in render_template'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:265:in render'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:348:in _render_with_layout'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:262:in render'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:1252:in render_for_file'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:936:in render_without_benchmark'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:51:in render'/var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'/usr/lib/ruby/1.8/benchmark.rb:308:实时'/var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:51:in render'/home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN/vendor/plugins/stories/app/controllers/stories_controller.rb:104:in show'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:135:in call'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:135:in custom'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:179:in call'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:179:in response'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:173:in each'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:173:in response'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:107:in respond_to'/home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN/vendor/plugins/stories/app/controllers/stories_controller.rb:102:in show'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:1333:in send'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:1333:in perform_action_without_filters'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/filters.rb:617:in call_filters'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/filters.rb:610:in perform_action_without_benchmark'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:68:in perform_action_without_rescue'/var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'/usr/lib/ruby/1.8/benchmark.rb:308:实时'/var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:68:in perform_action_without_rescue'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/rescue.rb:160:in perform_action_without_flash'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/flash.rb:151:in perform_action'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:532:in send'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:532:in process_without_filters'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/filters.rb:606:in process'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:391:in process'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:386:in call'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/routing/route_set.rb:438:in call'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:87:in dispatch'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:121:in _call'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:130:in build_middleware_stack'/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:29:in call'/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:29:in call'/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in cache'/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:9:in cache'/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:28:in call'/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in call'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/string_coercion.rb:25:in call'/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/head.rb:9:in call'/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/methodoverride.rb:24:in call'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/params_parser.rb:15:in call'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/session/cookie_store.rb:99:in call'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/failsafe.rb:26:in call'/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/lock.rb:11:in call'/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/lock.rb:11:in同步'/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/lock.rb:11:in call'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:114:in call'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/reloader.rb:34:in run'/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:108:in call'/var/lib/gems/1.8/gems/rails-2.3.14/lib/rails/rack/static.rb:31:in call'/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/urlmap.rb:47:in call'/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/urlmap.rb:41:in each'/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/urlmap.rb:41:in call'/var/lib/gems/1.8/gems/rails-2.3.14/lib/rails/rack/log_tailer.rb:17:in call'/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/content_length.rb:13:in call'/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/handler/webrick.rb:48:in service'/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in service'/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in run'/usr/lib/ruby/1.8/webrick/server.rb:173:in start_thread'/usr/lib/ruby/1.8/webrick/server.rb:162:in start'/usr/lib/ruby/1.8/webrick/server.rb:162:in start_thread'/usr/lib/ruby/1.8/webrick/server.rb:95:in start'/usr/lib/ruby/1.8/webrick/server.rb:92:in each'/usr/lib/ruby/1.8/webrick/server.rb:92:in start'/usr/lib/ruby/1.8/webrick/server.rb:23:in start'/usr/lib/ruby/1.8/webrick/server.rb:82:in start'/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/handler/webrick.rb:14:in run'/var/lib/gems/1.8/gems/rails-2.3.14/lib/commands/server.rb:111脚本/服务器:3:需要'脚本/服务器:3要求参数:{project_id"=>1",id"=>2"}显示会话转储回复标题:{缓存控制"=>无缓存",内容类型"=>文本/html"}

这是控制器的动作

def 显示@edit_allowed = User.current.allowed_to?(:edit_stories, @project)response_to do |格式|格式.html {渲染:模板=>故事/节目"}格式.apiformat.pdf { send_data(story_to_pdf(@story), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@story.id}.pdf") }结尾结尾

最后是视图的一部分

 link_to_if_authorized 'aa', {:controller =>"故事", :action =>"索引", :id =>@story.id, :project_id =>@story.project.id}, :title =>l(:view_story), :class =>'图标图标缩小'link_to_if_authorized 'bb', {:controller =>"故事", :action =>"编辑", :id =>@story.id, :project_id =>@story.project.id}, :title =>l(:button_edit), :class =>'图标图标编辑'link_to 'bb', {:id =>@story.id, :project_id =>@story.project.id}, :confirm =>'真的要删除吗?', :method =>:delete, :class =>'icon icon-del' 如果 User.current.allowed_to?(:delete_stories, @project)

也许重要的是,在生产模式下,插件是稳定的并且可以正确路由操作(包括显示)

解决方案

这通常是由于您(或其他人)从插件中修补核心模型(可能是 Project 模型)而没有采用 Rails 造成的重新加载器.

如果您覆盖方法(例如使用alias_method_chain)并且您的补丁加载了两次,您可以在调用旧方法时轻松创建无限循环.

# 这是我们的初始类我的课堂定义 foo放置原始 foo"结尾结尾模块补丁def self.included(base)base.alias_method_chain :foo, :feature结尾def foo_with_featurefoo_without_feature # 调用原始"方法放置带有功能的 foo"结尾结尾# 修补类MyClass.send(:include, 补丁)# 现在调用被修补的方法MyClass.new.foo# 印刷:# 原始 foo# foo 有特征

foo 现在引用方法 foo_with_feature 而原来的 foo 方法现在可以从 foo_without_feature 访问>

好的,直到现在一切看起来都很好.现在让我们看看会发生什么,如果我们再次加载我们的补丁

# 再次打补丁MyClass.send(:include, 补丁)# 并再次调用该方法MyClass.new.foo# SystemStackError: 堆栈级别太深# from (irb):7:in `foo_without_feature'# from (irb):7:in `foo'# 来自 (irb):27

您看到由无限循环引起的 SystemStackError.这是因为在第二次加载补丁后,foo_without_feature 现在引用了第一个补丁中的 foo_with_feature 方法.调用时,它会一遍又一遍地调用foo_without_feature,直到栈满.

你说它只在第二个请求时崩溃.这正是类重新加载器出现异常时的典型行为.默认情况下,Rails 会在开发模式下为每个请求重新加载所有类,但在生产模式下只会重新加载一次.

驯服 Rails 重装器有时有点棘手.作为一些一般准则,您应该

  1. 加载补丁时使用require_dependency代替require
  2. 使用加载补丁Dispatcher.to_prepare
  3. 总是声明打过补丁的类unloadable

最关键的部分是使用Dispatcher.to_prepare.它是一个回调,在生产模式下和开发模式下的每个请求之前调用一次,因此是加载补丁的理想场所.

顺便说一句:当使用 Redmine 2(或即将推出的 ChiliProject 4),即 Rails 3 时,类补丁将与这种方法大不相同 - 很可能更容易.

I'm developing a plugin for a management framework and when I start the webrick server in the development mode, a strange error raises(stack level too deep). It happens when an action (e.g. the show action) starts to render a template. Unfortunately i have no idea why this is happen.

SystemStackError in Stories#show

Showing vendor/plugins/stories/app/views/stories/show.rhtml where line #5 raised:

stack level too deep

Extracted source (around line #5):

    5: link_to_if_authorized 'aa', {:controller => "stories", :action => "index", :id => @story.id, :project_id => @story.project.id}, :title => l(:view_story), :class => 'icon icon-zoom-out'
    6: link_to_if_authorized 'bb', {:controller => "stories", :action => "edit", :id => @story.id, :project_id => @story.project.id}, :title => l(:button_edit), :class => 'icon icon-edit'
    7: link_to 'bb', {:id => @story.id, :project_id => @story.project.id}, :confirm => 'Really  delete?', :method => :delete, :class => 'icon icon-del' if User.current.allowed_to? (:delete_stories, @project)

    RAILS_ROOT: /home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN
    Application Trace | Framework Trace | Full Trace

    /var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/attribute_methods.rb:248:in method_missing'
    /var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/attribute_methods.rb:249:in method_missing'
     /var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/associations /association_proxy.rb:215:in send'
     /var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/associations/association_proxy.rb:215:in method_missing'
     /home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN/vendor/plugins/stories/app/views/stories/show.rhtml:5:in  _run_rhtml_vendor47plugins47stories47app47views47stories47show46rhtml'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/renderable.rb:34:in send'
      /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/renderable.rb:34:in render'
      /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:306:in with_template'
      /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/renderable.rb:30:in render'
      /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/template.rb:205:in render_template'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:265:in render'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:348:in _render_with_layout'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:262:in render'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:1252:in render_for_file'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:936:in render_without_benchmark'
    /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:51:in render'
    /var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'
    /usr/lib/ruby/1.8/benchmark.rb:308:in realtime'
    /var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'
    /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:51:in render'
/home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN/vendor/plugins/stories/app/controllers/stories_controller.rb:104:in show'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:135:in call'
      /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:135:in custom'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:179:in call'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:179:in respond'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:173:in each'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:173:in respond'
      /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:107:in respond_to'
    /home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN/vendor/plugins/stories/app/controllers/stories_controller.rb:102:in show'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:1333:in send'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:1333:in perform_action_without_filters'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/filters.rb:617:in call_filters'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/filters.rb:610:in perform_action_without_benchmark'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:68:in perform_action_without_rescue'
     /var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'
     /usr/lib/ruby/1.8/benchmark.rb:308:in realtime'
     /var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:68:in perform_action_without_rescue'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/rescue.rb:160:in perform_action_without_flash'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/flash.rb:151:in perform_action'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:532:in send'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:532:in process_without_filters'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/filters.rb:606:in process'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:391:in process'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:386:in call'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/routing/route_set.rb:438:in call'
     /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:87:in dispatch'
    /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:121:in _call'
    /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:130:in build_middleware_stack'
    /var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:29:in call'
    /var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:29:in call'
    /var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in cache'
     /var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:9:in cache'
     /var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:28:in call'
     /var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in call'
    /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/string_coercion.rb:25:in call'
    /var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/head.rb:9:in call'
    /var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/methodoverride.rb:24:in call'
    /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/params_parser.rb:15:in call'
    /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/session /cookie_store.rb:99:in call'
    /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/failsafe.rb:26:in call'
    /var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/lock.rb:11:in call'
    /var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/lock.rb:11:in synchronize'
    /var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/lock.rb:11:in call'
    /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:114:in call'
    /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/reloader.rb:34:in run'
    /var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:108:in call'
    /var/lib/gems/1.8/gems/rails-2.3.14/lib/rails/rack/static.rb:31:in call'
    /var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/urlmap.rb:47:in call'
    /var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/urlmap.rb:41:in each'
    /var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/urlmap.rb:41:in call'
    /var/lib/gems/1.8/gems/rails-2.3.14/lib/rails/rack/log_tailer.rb:17:in call'
    /var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/content_length.rb:13:in call'
    /var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/handler/webrick.rb:48:in service'
    /usr/lib/ruby/1.8/webrick/httpserver.rb:104:in service'
    /usr/lib/ruby/1.8/webrick/httpserver.rb:65:in run'
    /usr/lib/ruby/1.8/webrick/server.rb:173:in start_thread'
    /usr/lib/ruby/1.8/webrick/server.rb:162:in start'
    /usr/lib/ruby/1.8/webrick/server.rb:162:in start_thread'
    /usr/lib/ruby/1.8/webrick/server.rb:95:in start'
    /usr/lib/ruby/1.8/webrick/server.rb:92:in each'
    /usr/lib/ruby/1.8/webrick/server.rb:92:in start'
    /usr/lib/ruby/1.8/webrick/server.rb:23:in start'
    /usr/lib/ruby/1.8/webrick/server.rb:82:in start'
    /var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/handler/webrick.rb:14:in run'
    /var/lib/gems/1.8/gems/rails-2.3.14/lib/commands/server.rb:111
    script/server:3:in require'
    script/server:3
Request

Parameters:

{"project_id"=>"1",
 "id"=>"2"}

Show session dump
Response

Headers:

{"Cache-Control"=>"no-cache",
 "Content-Type"=>"text/html"}

and here is the action from the controller

def show 
 @edit_allowed = User.current.allowed_to?(:edit_stories, @project)
 respond_to do |format|
  format.html {
    render :template => 'stories/show'
  }
  format.api
  format.pdf  { send_data(story_to_pdf(@story), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@story.id}.pdf") }
 end                                
end

and at last a part of the view

     link_to_if_authorized 'aa', {:controller => "stories", :action => "index", :id => @story.id, :project_id => @story.project.id}, :title => l(:view_story), :class => 'icon icon-zoom-out'
     link_to_if_authorized 'bb', {:controller => "stories", :action => "edit", :id => @story.id, :project_id => @story.project.id}, :title => l(:button_edit), :class => 'icon icon-edit' 
    link_to 'bb', {:id => @story.id, :project_id => @story.project.id}, :confirm => 'Really delete?', :method => :delete, :class => 'icon icon-del' if User.current.allowed_to?(:delete_stories, @project) 

Maybe it's important to say, that in the production mode the plugin is stable and routes the actions (incl. show) correctly

解决方案

This is typically caused by you (or others) patching core models (probably the Project model) from a plugin without taking the rails reloader into account.

If you override methods (e.g. using alias_method_chain) and your patch is loaded twice, you can easily create an infinite loop when calling the old method.

# This is our initial class
class MyClass
  def foo
    puts "original foo"
  end
end

module Patch
  def self.included(base)
    base.alias_method_chain :foo, :feature
  end

  def foo_with_feature
    foo_without_feature # call the "original" method
    puts "foo with feature"
  end
end

# patch the class
MyClass.send(:include, Patch)

# Now call the patched method
MyClass.new.foo
# prints:
#   original foo
#   foo with feature

foo now refers to the method foo_with_feature while the original foo method now is accessible from foo_without_feature

All right, until now everything looked good. Now let's see what happens, if we load our patch again

# patch again
MyClass.send(:include, Patch)

# And call the method again
MyClass.new.foo
# SystemStackError: stack level too deep
#   from (irb):7:in `foo_without_feature'
#   from (irb):7:in `foo'
#   from (irb):27

You see a SystemStackError caused by an infinite loop. This is because after the second loading of the patch, foo_without_feature now refers to the foo_with_feature method from the first patch. When calling it, it will over and over again call foo_without_feature until the stack is full.

You said that it only crashes on the second request. This is exactly the typical behavior when something is odd on the class reloader. By default, Rails will reload all classes on every request in development mode but only once in production mode.

Taming the rails reloader is a bit tricky sometimes. As some general guidelines, you should

  1. use require_dependency instead of require when loading patches
  2. load your patches using Dispatcher.to_prepare
  3. always declare the patched classes unloadable

The most critical part is using Dispatcher.to_prepare. It is a callback which is called once in production mode and before each request in development mode and is thus the ideal place for loading patches.

As a side note though: When using Redmine 2 (or the upcoming ChiliProject 4), i.e. Rails 3, the class patching will be rather different from this approach - most probably easier.

这篇关于堆栈级别到深 Rails 2.3.14的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆