Ruby on rails 为什么ActionView';s";选择“U标签”;将HTML转义为它的";选项“;直接调用时的参数?

Ruby on rails 为什么ActionView';s";选择“U标签”;将HTML转义为它的";选项“;直接调用时的参数?,ruby-on-rails,activeview,Ruby On Rails,Activeview,因此,我一直在浏览ActionView中存在的非常糟糕的文档,特别是一个名为select\u tag的方法,它在从视图文件调用时就存在。应该是这样称呼的: select_tag name, option_tags, options 对名称一点也不说,对选项几乎不说,仅通过将其视为必须从其他函数获得的不透明值的示例来描述选项标签 和往常一样,了解Rails的唯一方法是对其进行反向工程 因此,我尝试直接从Rails控制台运行它,这很棘手,因为Ruby不允许您调用模块中定义的方法,除非您先创建类和对

因此,我一直在浏览ActionView中存在的非常糟糕的文档,特别是一个名为
select\u tag
的方法,它在从视图文件调用时就存在。应该是这样称呼的:

select_tag name, option_tags, options
名称
一点也不说,对
选项
几乎不说,仅通过将其视为必须从其他函数获得的不透明值的示例来描述
选项标签

和往常一样,了解Rails的唯一方法是对其进行反向工程

因此,我尝试直接从Rails控制台运行它,这很棘手,因为Ruby不允许您调用模块中定义的方法,除非您先创建类和对象:

class H
  include ActionView::Helpers::FormOptionsHelper
  include ActionView::Helpers::FormTagHelper
end

H.new.options_for_select ["foo","bar"]
上面使用的
options\u for\u select
来自其他人编写的实际代码。返回值是一个字符串:

"<option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option>"
返回值:

"<select name=\"my_name\" id=\"my_name\">&lt;option value=&quot;foo&quot;&gt;foo&lt;/option&gt;\n&lt;option value=&quot;bar&quot;&gt;bar&lt;/option&gt;</select>"
"<select name=\"name\" id=\"name\"><option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option></select>"
返回值:

"<select name=\"my_name\" id=\"my_name\">&lt;option value=&quot;foo&quot;&gt;foo&lt;/option&gt;\n&lt;option value=&quot;bar&quot;&gt;bar&lt;/option&gt;</select>"
"<select name=\"name\" id=\"name\"><option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option></select>"
“foo\nbar”

WTF是怎么回事?

在写这个问题的过程中,我无意中发现了它的答案:Ruby一直在骗我(就像它一直在骗我一样)

评估时:

H.new.options_for_select ["foo","bar"]
Ruby告诉您结果是一个字符串。但这仅仅是因为Pry和Irb都会在所有事情上无声地调用
.to\u s
,并且从
选项\u返回的东西有一个
to\u s
。真相:

(H.new.options_for_select ["foo","bar"]).class
=> ActiveSupport::SafeBuffer
ActiveSupport::SafeBuffer.new("<foo>")
=> "<foo>"
(H.new.options用于选择[“foo”,“bar]”)。类
=>ActiveSupport::SafeBuffer
ActiveSupport::SafeBuffer.new(“”)
=> ""
因此,编写这些方法的人假设您希望将原始的、用户提供的字符串合并到
标记中,并且这些字符串可能包含HTML/JavaScript注入的尝试,因此必须对它们进行转义

ActiveView将所有字符串视为可疑字符串,但可以通过将某些字符串包装在
ActiveSupport::SafeBuffer
中,将其标记为“安全”