1

I want to print some objects in a table having 2 rows per object, like this:

<tr class="title">
    <td>Name</td><td>Price</td>
</tr>
<tr class="content">
    <td>Content</td><td>123</td>
</tr>

I wrote a helper method in products_helper.rb, based on the answer of this question.

def write_products(products)
  products.map {
    |product|
    content_tag :tr, :class => "title" do
      content_tag :td do
        link_to h(product.name), product, :title=>product.name
      end
      content_tag :td do
        product.price
      end
    end
    content_tag :tr, :class => "content" do
      content_tag :td, h(product.content)
      content_tag :td, product.count
    end
  }.join
end

But this does not work as expected. It only returns the last node - the last <td>123</td>

What should I do to make it work?

1 Answer 1

2

Remember the function content_tag returns a string. It doesn't write directly to the page. So what you are doing with the TDs is this:

content_tag :tr do
  content_tag :td do
    link_to h(product.name), product, :title=>product.name
  end
  content_tag :td do
    product.price
  end
end

Which if we evaluate this partially would be

content_tag :tr do
  "<td title='Ducks'> <a ...>Ducks</a></td>"
  "<td>19</td>"
end

And in a block, the last value is the one that is returned. There are two strings present, but the first one just gets lost in the ether. The second string is the last value in the block and gets returned.

What you need to do is place a + between them to add the strings together :

content_tag :tr do
  (content_tag(:td) do
    link_to h(product.name), product, :title=>product.name
  end) + #SEE THE PLUS IS ADDED HERE
  (content_tag(:td) do
    product.price
  end)
end

You must do the same at the TR level, just put a plus in there after the end of the first content_tag.

Sign up to request clarification or add additional context in comments.

2 Comments

If I add a + between the 2 content_tags, I get an Internal Server Error: syntax error, unexpected tSYMBEG, expecting kDO or '{' or '('
I added parentheses around the content_tag s with do-end and around the arguments of the others like this: (content_tag :tr do content_tag(:td, ...)+content_tag(:td, ...) end) + (content_tag :tr do ... end)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.