1

I have an ActiveRecord collection which consists of a number of elements that each have a different type, (simplified names/variables) for example (if it were converted to a serializable_hash):

[
  {"id" => 1, "type" => "book", "title" => "title one"},
  {"id" => 2, "type" => "book", "title" => "title two"},
  {"id" => 3, "type" => "book", "title" => "title three"},
  {"id" => 4, "type" => "movie", "title" => "title four"},
  {"id" => 5, "type" => "movie", "title" => "title five"},
  {"id" => 6, "type" => "movie", "title" => "title six"}
]

Which I would like to output the following:

<h2>Book</h2>
<ul class="list-book">
  <li>title one</li>
  <li>title one</li>
  <li>title one</li>
</ul> 

<h2>Movie</h2>
<ul class="list-movie">
  <li>title three</li>
  <li>title four</li>
  <li>title five</li>
</ul>

I'm a bit confused about how I could go about achieving this output with HAML? So far I have begun something along the lines of:

- current_type = ""

- foo.each do |bar|
  - if current_type != bar.type
    %h2= bar.type

Then my confusion sets in when I try to think about how I could wrap each group of items in their own <ul> parent.

I've found myself being rather stumped on logic within HAML templates due to its nesting syntax, which leads me to believe that it truly is not the right place to carry out this logic, so perhaps if what I'm hoping for is impossible in HAML, is there a Ruby method to extract the unique type from the hash as an array and iterate over the collection by type instead?

waffl
  • 5,179
  • 10
  • 73
  • 123

1 Answers1

2

Try to think in terms of organising your data before writing it out to HTML. In this case you could use group_by on the collection first, then iterate over each array in turn, something like:

- foo.group_by {|m| m['type']}.each do |type, array|
  %h2= type.capitalize
  %ul{:class => "list-#{type}"}
    -array.each do |m|
      %li= m['title']

(Here I’ve just used capitalize to create the headers, you might need something more complex depending on what you want.)

matt
  • 78,533
  • 8
  • 163
  • 197