jflores
jflores

Reputation: 483

Nested content_tag in a table not escaping html

I was creating a Presenter in Rails3 and having trouble with a nested content tag. A code excerpt is below:

def lesson_activity_row
  lesson.activities.collect do |lesson_activity|
    content_tag :tr do 
      concat(content_tag :td, lesson_activity.activity
      concat(content_tag :td, lesson_activity.duration
      concat(content_tag :td, lesson_activity.agent
     end
   end
end

In my view, I'd get the following:

["<tr><td>New Activity</td><td>5 Minutes</td><td>Teacher</td></tr>", "<tr><td>New Activity</td><td>5 Minutes</td><td>Teacher</td></tr>"]

Upvotes: 0

Views: 437

Answers (1)

jflores
jflores

Reputation: 483

As I was looking, I couldn't really find any good answers to why this wasn't working and saw a host of questions that were either unanswered or weren't working for me. So, after looking at the methods I had available for Arrays and ActiveSupport::SafeBuffer, I came up with the following, which worked:

def lesson_activity_row
  lesson.activities.collect do |lesson_activity|
    content_tag :tr do 
      concat(content_tag :td, lesson_activity.activity
      concat(content_tag :td, lesson_activity.duration
      concat(content_tag :td, lesson_activity.agent
     end.to_s #note the to_s
   end.join.html_safe #note join.html_safe
end

Many of the solutions I saw included using "joins", but content_tag here isn't returning an array. It's returning an instance of ActiveSupport::SafeBuffer and #join isn't a method for that object. to_s, however, is.

Of course, this content_tag is nested inside of lesson.activities.collect, which is an array and, of course, #join is a method that can be called on Array. And #html_safe escapes the html.

Hope this helps someone else!

Upvotes: 1

Related Questions