【问题标题】:Error from inside ActionView::Template::Error - String can't be coerced into Integer来自 ActionView::Template::Error 内部的错误 - 不能将字符串强制转换为整数
【发布时间】:2026-01-09 07:15:01
【问题描述】:

我们最近更新了应用程序的 ruby​​ 和 ruby​​gems 版本,并且一直收到以下错误:

A TypeError occurred in [model]#[view]:

String can't be coerced into Integer
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_view/template/error.rb:92:in `+'

这是回溯:

vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_view/template/error.rb:92:in `+'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_view/template/error.rb:92:in `sum'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_view/template/error.rb:92:in `source_extract'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_view/template/error.rb:112:in `annoted_source_code'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/debug_exceptions.rb:68:in `block in log_error'
vendor/bundle/ruby/2.5.0/gems/activesupport-3.2.22.5/lib/active_support/deprecation/reporting.rb:20:in `silence'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/debug_exceptions.rb:66:in `log_error'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/debug_exceptions.rb:34:in `render_exception'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/debug_exceptions.rb:27:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/exception_notification-4.1.1/lib/exception_notification/rack.rb:32:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/rack/logger.rb:32:in `call_app'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/rack/logger.rb:16:in `block in call'
vendor/bundle/ruby/2.5.0/gems/activesupport-3.2.22.5/lib/active_support/tagged_logging.rb:22:in `tagged'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/rack/logger.rb:16:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/request_id.rb:22:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-1.4.7/lib/rack/methodoverride.rb:21:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-1.4.7/lib/rack/runtime.rb:17:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/activesupport-3.2.22.5/lib/active_support/cache/strategy/local_cache.rb:72:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-1.4.7/lib/rack/lock.rb:15:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-1.4.7/lib/rack/deflater.rb:13:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/static.rb:83:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-ssl-1.3.4/lib/rack/ssl.rb:27:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-cache-1.7.2/lib/rack/cache/context.rb:140:in `forward'
vendor/bundle/ruby/2.5.0/gems/rack-cache-1.7.2/lib/rack/cache/context.rb:249:in `fetch'
vendor/bundle/ruby/2.5.0/gems/rack-cache-1.7.2/lib/rack/cache/context.rb:189:in `lookup'
vendor/bundle/ruby/2.5.0/gems/rack-cache-1.7.2/lib/rack/cache/context.rb:66:in `call!'
vendor/bundle/ruby/2.5.0/gems/rack-cache-1.7.2/lib/rack/cache/context.rb:51:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
lib/rack/assets.rb:167:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
lib/rack/basics.rb:24:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/engine.rb:484:in `call'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/application.rb:231:in `call'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/railtie/configurable.rb:30:in `method_missing'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:606:in `process_client'
config/unicorn.rb:94:in `process_client_with_gc'
vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:701:in `worker_loop'
vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:549:in `spawn_missing_workers'
vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:142:in `start'
vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.0/bin/unicorn:126:in `<top (required)>'
vendor/bundle/ruby/2.5.0/bin/unicorn:23:in `load'
vendor/bundle/ruby/2.5.0/bin/unicorn:23:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli/exec.rb:75:in `load'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli/exec.rb:75:in `kernel_load'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli/exec.rb:28:in `run'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli.rb:424:in `exec'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli.rb:27:in `dispatch'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli.rb:18:in `start'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/exe/bundle:30:in `block in <top (required)>'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/friendly_errors.rb:122:in `with_friendly_errors'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/exe/bundle:22:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/bin/bundle:23:in `load'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/bin/bundle:23:in `<main>'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/bin/ruby_executable_hooks:15:in `eval'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/bin/ruby_executable_hooks:15:in `<main>'

我试图了解为什么会发生此错误。根据回溯,它似乎不是由我们的代码引起的,而且由于它只发生在网站的某些页面上,我不认为它是 gem 兼容性问题。值得注意的是,ActionView::Template::Error 代码正在对字符串数组调用 sum:

79  def source_extract(indentation = 0)
80    return unless num = line_number
81    num = num.to_i
82
83    source_code = @template.source.split("\n")
84
85    start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max
86    end_on_line   = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min
87
88    indent = ' ' * indentation
89    line_counter = start_on_line
90    return unless source_code = source_code[start_on_line..end_on_line]
91
92    source_code.sum do |line|
93      line_counter += 1
94      "#{indent}#{line_counter}: #{line}\n"
95    end
96  end

但这似乎是对 Array#sum 方法 (https://ruby-doc.org/core-2.5.1/Array.html#method-i-sum) 的有效使用。这是我们的代码库有问题还是 ActionPack gem 中有错误?

这里是相关的,除了我们的 config/unicorn.rb:

93  def process_client_with_gc(client)
94    res = process_client_without_gc(client)
95    possibly_run_gc
96    res
97  end
98
99  alias_method :process_client_without_gc, :process_client
100 alias_method :process_client, :process_client_with_gc

【问题讨论】:

  • 这条线怎么样? config/unicorn.rb:94:in process_client_with_gc'`
  • 在帖子中添加了一些相关信息。解释一下,'process_client_with_gc' 只是调用 Unicorn 的 'process_client' 然后在已经处理了大量客户端的情况下运行垃圾收集器(那是 'possibly_run_gc',只是一个带有 fudge 因子的计数器)。
  • Tim 这里似乎有些混乱。由于您使用 ruby​​ >= 2.4,它支持 Enumerable#sum 作为核心的一部分,但您使用的是 rails 3.2,它以不同的方式实现 Enumerable#sum(例如 enum.inject(:+))。我不确定为什么核心实现优先于 rails 版本(我会假设相反),但这就是你的问题。
  • 建议:1) 升级 rails 版本,考虑到需要的潜在版本跳转,这可能会很耗时且可能很困难 2) 降级 ruby​​ 版本要容易得多,因为您只需要回退到 2.3。间歇性行为的原因是,这实际上是在出现另一个错误并且 action_view 试图向您显示错误但在此过程中导致其自身的错误时发生的。
  • 您的实际错误可能发生在process_client_with_gclib/rack/*.rb

标签: ruby ruby-on-rails-3 ruby-on-rails-3.2 actionview


【解决方案1】:

感谢engineersmnkyTom Lord 提供他们的解决方案。

问题在于 ruby​​ >= 2.4 支持 Enumerable#sum 作为核心的一部分,但 rails 3.2 也实现了 Enumerable#sum。这两种实现方式是不同的。似乎核心实现优先于 rails 版本,这会导致上述错误。

解决方案:

  1. 升级 rails 版本,考虑到可能需要的版本跳转,这可能会很耗时且可能很困难
  2. 降级 ruby​​ 版本。这对我来说要容易得多,因为我只需要降回 2.3。

【讨论】:

  • Ruby 2.4 支持是added to Rails 4.2.8。它不适用于旧版本的导轨。
  • 你说得对,例如,Rails 3.2 没有指定最大的 ruby​​ 版本——但那是因为它与当时最新的 ruby​​ 兼容,并且无法预测该语言的未来! Rails 3.2.22 于 2015 年 6 月 16 日发布; Ruby 2.4 于 2016 年 12 月 25 日发布。
  • 您降级 ruby​​ 的“解决方案”是有效的,但值得注意的是 rails 3 已经报废;没有更多的安全补丁,许多库已经放弃了对它的支持。所以对于任何“严肃”的项目,尽快升级很重要。