1

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
4
  • Can you provide an example of the nested list you want as a result? Commented Apr 16, 2017 at 21:45
  • I've just added a picture displaying what I want to achieve. I put all the code in the view but I really want to use helper. Commented Apr 16, 2017 at 22:37
  • So, you want to display the bookmarks that are in the hash or the bookmarks that belong to each website (model association) or both (i.e. are in the hash and belong to website)? Commented Apr 17, 2017 at 3:22
  • @Gerry This helper is intended to help me present search result to the user who searches through bookmarks. So only these in the results hash - according to ids in results hash. In results hash that return search results I keep website id as a key and bookmark ids as either an array or single value. I want to display websites in main list and bookmarks of each website as sublists and probably add some more details and links to bookmarks from database. Maybe my search method produces complicated results but this is the only way I've found to avoid webiste duplication in the list. Commented Apr 17, 2017 at 8:01

1 Answer 1

1

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.

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

3 Comments

Thanks! One more thing is there a way I could mix this html with rendering partials?
Sure, just call the helper method with <%= present_search_results(results) %> inside the partial, where you want the list to be displayed.
I meant calling render within helper but I figured it out thanks ;)

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.