Gregg
Gregg

Reputation: 125

Ruby on Rails Custom Helper outputting HTML nested list

as in title I'm trying to create helper that does that but I'm struggling. I'm getting errors or simply empty list like this: enter image description here

And I want to achieve this: enter image description here There is to much logic to simply put this code in view. A results is a hash where the key is a website id and value is either an array of bookmarks ids or just bookmark id.

My code:

module WebsitesHelper
  def present_search_results(results)
    content_tag(:ul, class: "websites-list") do
      results.each do |key, value|
        website = Website.find(key)
        concat(content_tag(:li, website.url, class: "website-#{key}") do
          bookmarks = website.bookmarks.select do |b|
            if value.is_a?(Array)
              value.include?(b.id)
            else
              value = b.id
            end  
          end
          content_tag(:ul, nil, id: "website-#{key}") do
            bookmarks.each do |b|
              content_tag(:li, b.title)
            end
          end
        end)      
      end
    end  
  end
end

Upvotes: 1

Views: 885

Answers (1)

Gerry
Gerry

Reputation: 10497

If you want to stick with helpers, then something like this could help:

def present_search_results(results)
  content_tag(:ul, class: "websites-list") do

    results.map do |website_id, bookmarks|
      bookmarks = [bookmarks] unless bookmarks.is_a?(Array)

      content_tag(:li, class: "website-#{website_id}") do
        website = Website.find(website_id)
        concat(website.url)
        concat(
          content_tag(:ul, class: "bookmarks-list") do

            bookmarks.map do |bookmark_id| 
              bookmark = Bookmark.find(bookmark_id)
              content_tag(:li, bookmark.title)
            end.reduce(:+)
          end
        )
      end
    end.reduce(:+)
  end
end

But, in my opinion, that code is not easy to read, so you could use plain html instead, like this:

def present_search_results(results)
  list = "<ul class='websites-list'>"

  results.each do |(website_id, bookmarks)|
    bookmarks = [bookmarks] unless bookmarks.is_a?(Array)
    website   = Website.find(website_id)

    list += "<li class='website-#{website_id}'>#{website}"
    list += "<ul class='bookmarks-list'>"

    bookmarks.each do |bookmark_id|
      bookmark = Bookmark.find(bookmark_id)
      list += "<li>#{bookmark.title}</li>"
    end

    list += "</ul></li>"
  end

  list += "</ul>"
  list.html_safe
end

I like this one better, since it is easier to read. But both with output the list you want.

Upvotes: 1

Related Questions