我可以在 Rails 中使用 link_to 创建一个链接数组吗?

Posted

技术标签:

【中文标题】我可以在 Rails 中使用 link_to 创建一个链接数组吗?【英文标题】:Can I make an array of links using link_to in Rails? 【发布时间】:2013-07-07 19:36:03 【问题描述】:

我有一个要显示的 url/title 对中的值列表。 (更具体地说,每个对象都有自己的链接列表,有些是 0,有些是 1,有些是更多。)我希望它们出现在逗号分隔的列表中。所以我在我的 .erb 文件中写了这个:

<%= links.map|wl| link_to wl.title, wl.url.join(', ') %>

令我惊讶的是,这显示了一个逗号分隔的html 代码列表我想创建的链接;也就是说,它采用了所有尖括号并对它们进行&符号编码。为了确保在高阶函数中没有什么有趣的东西,我尝试了一个更命令式的版本:

<% a = [] %>
<% links.each do |wl| %>
  <% a << link_to(wl.title, wl.url) %>
<% end %>
<%= a.join(', ') %>

当然,结果相同。但我不认为我在滥用link_to,因为如果我将其修改为

<% links.each do |wl| %>
  <%= link_to(wl.title, wl.url) %>,
<% end %>

然后它实际上创建了链接。 几乎正是我想要的,除了最后一个逗号之后有一个额外的逗号。 link_to 的幕后是否有一些魔力,使其根据输出的方向而采取不同的行动?有没有办法绕过这个魔法? join 语义正是我在这里想要的,我显然可以弄清楚如何滚动我自己的(使用 each_index,我猜)但它似乎是一个非常繁重且非 Ruby 的解决方案,必须是一个常见的问题.

【问题讨论】:

? 【参考方案1】:

在分隔符字符串上使用safe_joinhtml_safe

例子:

<%= safe_join(links.map  |l| link_to(l.title, l.url) , ", ".html_safe) %>

【讨论】:

你是国王! 是否需要逗号上的 html_safe?逗号没有html安全项,对吧? 如果您将", " 之类的非 html 安全字符串与安全 html 字符串混合使用,则结果是非 html 安全字符串并将被转义,因此您需要明确指出您的常量字符串是 html_safe。 【参考方案2】:

试试

<%= links.map|wl| link_to wl.title, wl.url.join(', ').html_safe %>

这指示 Rails 不要转义文本。

【讨论】:

我喜欢这个答案,因为它减少了间接性。间接性通常不利于可读性和可维护性。 如果您这样做,请非常小心。当 wl.title 来自外部来源时,这是一个可利用的漏洞。使用h(wl.title),或者更好的是使用safe_join @levinalex 不会link_to 已经返回一个安全值吗?你能举一个漏洞利用的例子吗?【参考方案3】:

虽然使用html_safe 的建议会得到你想要的结果,但我建议你不要在你的视图中坚持这样的循环。在 Rails 中有一个非常好的方法来做你正在寻找的事情:

在您当前拥有循环的主视图文件中,将其更改为:

<%= render partial: 'links/link', collection: links, spacer_template: 'shared/comma' %>

然后创建一个部分links/_link.html.erb

<%= link_to link.title, link.url %>

然后创建一个部分shared/_comma.html.erb

,

这种方法的好处是您不必担心您的链接内容是否真的安全,并且如果您选择以另一种方式列出或设置它的样式,它就像更改一个或两个模板一样简单。例如,如果您决定使用垂直而不是逗号,并在间隔模板中使用 &lt;br&gt; 而不是 ,

【讨论】:

啊,谢谢!我有预感会有类似html_safe 的东西,但this 是我真正想要的——我知道这必须有一个成语。此问题的未来读者请注意:我确实必须对包含部分链接的文件强制使用 no-EOL-at-EOF,以防止链接和逗号之间出现空格,但是一旦我这样做了,它就可以完美地工作。跨度> 这有很多间接性。似乎不是最好的设计。 间接性通常不利于可读性和可维护性。也许,如果你解释为什么在视图中粘贴循环是不好的,我会更理解你的推理。 Martin,循环在视图中不好,因为代码在视图中不好。它不属于它。我想坚持回答最初的问题,但为了更进一步,我什至不会做我上面建议的事情。我实际上会有一个装饰者/演示者使用一个名为links 的方法来支持这个视图。该方法实际上基本上可以完成我上面的操作,因此您仍然可以拥有部分内容,但是您的***视图可以拥有像 &lt;%= @my_presenter.links %&gt; 这样简单的东西,这比循环或一大块数组操作更具可读性和可理解性。 @AlexPeachey 虽然我通常同意视图中没有太多代码的精神,但我认为理想不一定是“没有代码”,而是“没有逻辑”。迭代不是逻辑,它是完全可读的。你真的会有一个内容是一个逗号的部分吗?这并没有增加很多价值。你所做的只是让开发人员以制作一个简单的东西列表的名义处理更多文件。【参考方案4】:

试着把它放在你的 ApplicationHelper 中

  def sep(separator)
    ->(a, b) a << separator.html_safe << b 
  end

然后在您的模板中执行此操作

links.map|wl| link_to wl.title, wl.url.reduce(&sep(", "))

您可以通过这种方式使用任何您喜欢的分隔符。你也不需要打电话给html_safe。只有分隔符。所以这种方法更安全。

【讨论】:

【参考方案5】:

Rails 默认将字符串转换为 html 安全的。您的 join 调用将链接输出转换为字符串,这就是文本被转义的原因。尝试在 join 调用之后添加 .html_safe ,这将告诉 rails 您提供的文本是 html 安全的,因此不需要转义。有关其工作原理的更多信息,请访问:http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/

【讨论】:

这与 Jim Lim 的回答存在相同的问题,会使您的代码面临容易被利用的漏洞的风险。使用safe_join【参考方案6】:

您可以使用 RAW:

= raw inks.map|wl| link_to wl.title, wl.url.join(', ')

或者

= render partial: 'links/link', collection: links, spacer_template: 'shared/comma' 

亚历克斯·皮奇建议

【讨论】:

以上是关于我可以在 Rails 中使用 link_to 创建一个链接数组吗?的主要内容,如果未能解决你的问题,请参考以下文章

Rails link_to 最后一个脚手架项目

Rails 5使用link_to更新日期

Rails 视图:创建菜单

在rails中带有jquery参数的link_to

Rails:在 link_to 中保留 GET 查询字符串参数

使用 link_to Rails 设置会话变量