Suppose I have the following string

@x = "<a href='#'>Turn me into a link</a>"

In my view, I want a link to be displayed. That is, I don't want everything in @x to be unescaped and displayed as a string. What's the difference between using

<%= raw @x %>
<%= h @x %>
<%= @x.html_safe %>


6 Answers 11

up vote 365 down vote accepted

Considering Rails 3:

html_safe actually "sets the string" as HTML Safe (it's a little more complicated than that, but it's basically it). This way, you can return HTML Safe strings from helpers or models at will.

h can only be used from within a controller or view, since it's from a helper. It will force the output to be escaped. It's not really deprecated, but you most likely won't use it anymore: the only usage is to "revert" an html_safe declaration, pretty unusual.

Prepending your expression with raw is actually equivalent to calling to_s chained with html_safe on it, but is declared on a helper, just like h, so it can only be used on controllers and views.

"SafeBuffers and Rails 3.0" is a nice explanation on how the SafeBuffers (the class that does the html_safe magic) work.

39 upvote
I wouldn't say that h will ever be deprecated. Using "Hi<br/>#{h@}".html_safe is quite common and an accepted use. – maletor
1 upvote
@Maletor interesting usage, though I still think it falls into the "unusual" category. – Fábio Batista
10 upvote
@Fábio Batista Not unusual at all, here it is in a Railscast at the bottom: – William Jones
5 upvote
String#html_safe actually returns an instance of ActiveSupport::SafeBuffer which wraps the original string and is #html_safe? . The original string does not become #html_safe? after calling #html_safe on it. – jmaxyz
Thanks for the complement, @greenagain… I intentionally simplified the explanation and included a link to SafeBuffer's complete article for those curious enough. – Fábio Batista
8 upvote
Note that there is a subtle difference between raw and html_safe in practice: raw(nil) returns an empty string, while nil.html_safe throws an exception. – Van der Hoorn
Great linked article for people who want to know what's really going on behind the magic of Rails' views -- thanks! – Daniel Doezema
so why the heck is html_safe stripping out hyphens from my urls? – jenson-button-event
2 upvote
h will not "revert" an html_safe declaration. When an string is html_safe, h will do nothing. – GuiGS

I think it bears repeating: html_safe does not HTML-escape your string. In fact, it will prevent your string from being escaped.

<%= "<script>alert('Hello!')</script>" %>

will put:


into your HTML source (yay, so safe!), while:

<%= "<script>alert('Hello!')</script>".html_safe %>

will pop up the alert dialog (are you sure that's what you want?). So you probably don't want to call html_safe on any user-entered strings.

62 upvote
In other words, html_safe is not "please make this html safe", it's the opposite - it is you the programmer telling rails that "this string is html safe, promise!" – PaulMurrayCbr
8 upvote
it really should be renamed to .unescape_html in the rails source code.. – Magne
actually I came here to figure out if it actually does unescape or if it just makes a mark that it is not necessary to_escape. Quite a difference. Oh well, off to read the source code then. – Simon B.

The difference is between Rails’ html_safe() and raw(). There is an excellent post by Yehuda Katz on this, and it really boils down to this:

def raw(stringish)



Yes, raw() is a wrapper around html_safe() that forces the input to String and then calls html_safe() on it. It’s also the case that raw() is a helper in a module whereas html_safe() is a method on the String class which makes a new ActiveSupport::SafeBuffer instance — that has a @dirty flag in it.

Refer to "Rails’ html_safe vs. raw".

In Simple Rails terms:

h remove html tags into number characters so that rendering won't break your html

html_safe sets a boolean in string so that the string is considered as html save

raw It converts to html_safe to string

h is html_safe, which means the HTML is rendered as-is. – Dave Newton
  1. html_safe :

    Marks a string as trusted safe. It will be inserted into HTML with no additional escaping performed.

    #=> "<a>Hello</a>"
    #=> NoMethodError: undefined method `html_safe' for nil:NilClass
  2. raw :

    raw is just a wrapper around html_safe. Use raw if there are chances that the string will be nil.

    #=> "<a>Hello</a>"
    #=> ""
  3. h alias for html_escape :

    A utility method for escaping HTML tag characters. Use this method to escape any unsafe content.

    In Rails 3 and above it is used by default so you don't need to use this method explicitly

The best safe way is: <%= sanitize @x %>

It will avoid XSS!

Not the answer you're looking for? Browse other questions tagged or ask your own question.