I have a rails gem that uses a snippet like:
components = []
components << label_for(attribute)
components << ...
components << text_field(attribute)
return components.join
The gem worked fine in Rails 3.0.1, however it escapes (renders as text in a browser) all HTML after updating to Rails 3.0.2. What am I doing something wrong? Thanks.
As @sj26 points out, either use the rails built-in helper:
<%= safe_join(components) %>
Or use my rails_join gem to make Array#join html-safe aware, in which case your original code will work as is.
String#join isn't SafeBuffer-aware.
String#html_safe marks that you string is already HTML-escaped, preventing users sneaking bits of HTML into your pages. Check out this post by Yehuda Katz on SafeBuffer and why/how you should be using them.
If you have an array of String and SafeBuffer you want to concatenate, make sure you've run #html_safe on them all, or #concat them into a SafeBuffer like so:
['<one>', '<p>two</p>'.html_safe].inject ''.html_safe, &:concat
=> "<one><p>two</p>" 
Rails has a built-in helper called safe_join which will do this for you.
http://makandra.com/notes/954-don-t-mix-array-join-and-string-html_safe
class Array
  def html_safe_join(delimiter='')
    ''.html_safe.tap do |str|
      each_with_index do |element, i|
        str << delimiter if i > 0
        str << element
      end
    end
  end
end
[safe_string, unsafe_string].html_safe_join(' ') 
# '<span>foo</span><span&t;bar</span>'
                        Strings are automatically HTML-escaped in Rails3. You need to change that last line to:
return components.join.html_safe
alternately, if editing the gem is too much hassle you can do it from the view:
<%= helper_name.html_safe %>
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With