本文介绍了为什么在 ActionView::OutputBuffer 上调用 URI.escape 会失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将应用程序从 Rails 2 升级到 Rails 3.显然,调用 render() 现在返回 ActionView::OutputBuffer 而不是 String.我需要将 render() 的结果传递给 URI.escape(),这会失败并出现异常...

I'm upgrading an application from Rails 2 to Rails 3. Apparently, calling render() now returns ActionView::OutputBuffer and not String. I need to pass the results of render() to URI.escape(), and this fails with exception...

ob = ActionView::OutputBuffer.new("test test")
URI.escape(ob)
    `NoMethodError: undefined method 'each_byte' for nil:NilClass`.
        from /opt/ruby19/lib/ruby/1.9.1/uri/common.rb:307:in `block in escape'
        from ..../ruby/1.9.1/gems/activesupport-3.2.1/lib/active_support/core_ext/string/output_safety.rb:160:in `gsub'
        from ..../ruby/1.9.1/gems/activesupport-3.2.1/lib/active_support/core_ext/string/output_safety.rb:160:in `gsub'
        from /opt/ruby19/lib/ruby/1.9.1/uri/common.rb:304:in `escape'
        from /opt/ruby19/lib/ruby/1.9.1/uri/common.rb:623:in `escape'

此外,在 OutputBuffer 上调用 to_s 会返回相同的 OutputBuffer 类,所以我什至无法将此缓冲区转换为诚实的字符串?

Moreover, calling to_s on OutputBuffer returns same OutputBuffer class, so I cannot even convert this buffer into a honest string?

ob.to_s.class
    ActionView::OutputBuffer

当然,调用 URI.escape("test test") 会按预期返回test%20test",所以这不是 URI 问题.

Of course, calling URI.escape("test test") returns "test%20test" as expected, so this is not URI problem.

环境:

  • ruby 1.9.3p125(2012-02-16 修订版 34643)[i686-linux]
  • Rails 3.2.1

我的问题是:为什么会发生这种情况,我该如何解决这个问题?

更新:显然,使用 '' + ob 作为 ob.to_s 的一种形式将 OutputBuffer 转换为 String,这有效地解决了问题......但我的问题为什么会发生"仍然存在,例如这是一个错误,我应该报告它,还是我做错了什么?

Update: Apparently, using '' + ob as a form of ob.to_s converts OutputBuffer to String, which effectively works around the problem... But my question 'why does this happen' still remains, e.g. is this a bug, should I report it, or I'm doing something wrong?

推荐答案

这是一个 Rails 中的错误:

当调用带有 ActiveSupport::SafeBuffer 上的块的 gsub 时,用于引用子匹配的全局变量 $1、$2 等在调用块时并不总是正确设置(不再?).

这就是 URI.escape(以及任何其他使用 gsub() 的函数在 ActiveSupprt::Safebuffer 上会失败的原因.

This is why URI.escape (and any other function that uses gsub() will fail on ActiveSupprt::Safebuffer.

几个讨论,显然现在最安全的路线是在将 SafeBuffer 传递给任何可以调用 gsub 的东西之前调用 to_str,例如URI.encodeescape_javascript 和类似的功能.

There are several discussions about this, apparently the safest route right now is to call to_str before passing SafeBuffer to anything that can call gsub, e.g. URI.encode, escape_javascript and similar functions.

我关于 to_s 返回相同类的另一个问题 - 显然安全缓冲区将返回自身而不是裸字符串,这是设计使然.为了得到一个真正的String,可以使用.to_str.

My other quesion about to_s returning the same class - obviously safe buffer will return itself and not a bare String, this is by design. In order to get a true String, .to_str can be used.

这篇关于为什么在 ActionView::OutputBuffer 上调用 URI.escape 会失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 15:37