问题描述
我正在将应用程序从 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.encode
、escape_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 会失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!