简体   繁体   中英

Rails: link_to method

I have something like this:

<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>

Which gives me

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

Instead of Java and CSS links. What am I missing?

It's because strings in Rails 3 are, by default, not considered HTML-safe. See this blog post about it.

You can manually mark something as safe by calling .html_safe on it, which would make your code like so:

<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>

But I'd recommend doing this instead:

<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>

I think html_safe is what you are looking for! So this would solve the problem (@post.tags.collect {|c| (link_to c.name, c)}.join(", ")).html_safe

I think your tag names should be input by the user, right?

In this case, html_safe is not your first choice, as it gave full trust to the user. And your site would encounter XSS attacks.

The better choice should be sanitize . See the reference here: http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html

As you only want to have links, the following line do what you want:

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

Note the use of strip_links(c.name) , this removes all the links that input by the user.

Let's assume the tag names are: ["Product", " hi ", "bye"]

By just using .html_safe , the following would be shown:

<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>

But using the mix of sanitize with strip_links, the following is the result:

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

Or you could mix the use of strip_tags with .html_safe :

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

This simply removes all tags in c.name before you call the html_safe.

I would suggest (and you probably are doing already :D) removing all unwanted tags before storing into the database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM