Rails:link_to方法

时间:2011-01-11 02:27:51

标签: ruby-on-rails

我有这样的事情:

<p>
  <b>Tags:</b>
  <%if @post.tags.count > 0%>
    <%= @post.tags.collect {|c| (link_to c.name, c)}.join(", ")%>
  <%else%>
    Does not have any tags.
  <%end%>
</p>

哪个给了我

Tags: <a href="/tags/1">Java</a>, <a href="/tags/2">CSS</a>

而不是Java和CSS链接。我错过了什么?

3 个答案:

答案 0 :(得分:6)

这是因为默认情况下,Rails 3中的字符串不被视为HTML安全。请参阅this blog post

您可以通过调用.html_safe来手动将某些内容标记为安全,这会使您的代码如此:

<p>
  <b>Tags:</b>
  <%if @post.tags.count > 0%>
    <%= @post.tags.collect {|c| (link_to c.name, c)}.join(", ").html_safe %>
  <%else%>
    Does not have any tags.
  <%end%>
</p>

但我建议改为:

<p>
  <b>Tags:</b>
  <% if @post.tags.count > 0%>
    <% @post.tags.each_with_index do |tag, i| %>
      <%= link_to h(tag.name), tag %><%= ', ' if i < @post.tags.size - 1 %>
    <% end %>
  <% else %>
    Does not have any tags.
  <%end%>
</p>

答案 1 :(得分:3)

我认为html_safe正是你要找的! 所以这可以解决问题(@ post.tags.collect {| c |(link_to c.name,c)}。join(“,”))。html_safe

答案 2 :(得分:1)

我认为您的标签名称应由用户输入,对吧?

在这种情况下,html_safe不是您的首选,因为它完全信任用户。您的网站将遭遇XSS攻击。

更好的选择应该是sanitize。请参阅此处的参考:http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html

由于您只想拥有链接,因此以下行符合您的要求:

<%= sanitize @post.tags.collect {|c| (link_to strip_links(c.name), c)}.join(", "), :tags => %w(a) %>

请注意strip_links(c.name)的使用,这将删除用户输入的所有链接。

我们假设标签名称为:[“Product”,“ hi ”,“bye”]

只需使用.html_safe,就会显示以下内容:

<a href="/tags/1">Product</a>, <a href="/tags/2"><strong>hi</strong></a>, <a href="/tags/3"><a href='bad_site.com'>bye</a></a>

但是使用sanitize和strip_links的混合,结果如下:

<a href="/tags/1">Product</a>, <a href="/tags/2">&lt;strong&gt;hi&lt;/strong&gt;</a>, <a href="/tags/3">bye</a>

或者您可以将strip_tags.html_safe混合使用:

<%= @post.tags.collect {|c| (link_to strip_tags(c.name), c)}.join(", ").html_safe %>

在您调用html_safe之前,这只会删除c.name中的所有代码。

我建议(你可能已经做过了:D)在存储到数据库之前删除所有不需要的标签。