enjaku
enjaku

Reputation: 346

Render html from helper in RoR

I have a method in a helper, here is the code:

    def top_menu_output(parent = Category.where(parent_id: nil))
    parent.each do |p|
      content_tag(:li) do
        parent_id = p.id
        if Category.where(parent_id: parent_id).exists?
          link_to(p.title, p.page_name, class: "parent")
          content_tag(:ul, class: "unstyled") do
            subparent = Category.where(parent_id: parent_id)
            content_tag(:li) do
              top_menu_output(subparent)
            end
          end
        elsif
          link_to(p.title, p.page_name)
        end
      end
    end
  end

and I call the method in a view like this

 <%top_menu_output%>

but it renders nothing. What do I do to render all the links and li's? Thank you for your answers.

P.S. If I put the code right in the view it works just fine, but the view is obviously not the right place for the method.

P.P.S. If I call the method like this <%=top_menu_output%> it renders all the stuff from my db CATEGORY ID: 1, PARENT_ID: NIL, PAGE_NAME: "", KEYWORDS: "", DESCRIPTION: "", SEO_TEXT_LEFT: "", SEO_TEXT_RIGHT: "", CREATED_AT: "2014-04-19 22:08:55", UPDATED_AT: "2014-04-19 22:08:55"...

Upvotes: 0

Views: 987

Answers (2)

enjaku
enjaku

Reputation: 346

Thanks Frederick, changing each to collect is almost what I want. But it is also necessary to use concat and + so the properly working method is:

def top_menu_output(parent = Category.where(parent_id: nil))
    parent.collect do |p|
      content_tag(:li) do
        parent_id = p.id
        if Category.where(parent_id: parent_id).exists?
          link_to(p.title, p.page_name, class: "parent") +
          content_tag(:ul, class: "unstyled js-menu") do
            subparent = Category.where(parent_id: parent_id)
            top_menu_output(subparent)
          end
        elsif
          concat link_to(p.title, p.page_name)
        end
      end
    end.join.html_safe
  end

Upvotes: 0

Frederick Cheung
Frederick Cheung

Reputation: 84182

The return value of each is the collection that is iterated over, so you are generating a whole bunch of html but then returning something else

You could change that to

parent.collect do |p|
  content_tag(:li) do
    ...
  end
end.join

This would collect the html generated by each iteration through the block, concatenate them all and return that. As pointed out in the comments, you also need to use <%= or you'll never see any output

Upvotes: 1

Related Questions