Предположим, ваша модель называется Event
, и у нее есть атрибут date
, а ваша коллекция называется @events
, вот одна из идей: представьте это на ваш взгляд ...
<ul>
<%= render @events, locals: { events: @events } %>
</ul>
... тогда у вас будет партиал с именем _event.html.erb
, который выглядит следующим образом:
<% last_event = event_counter == 0 ? nil : events[event_counter - 1]
next_event = events[event_counter + 1]
%>
<% if last_event && last_event.date != event.date
# add a new date header and start a new nested list of events
%>
<li><h3><%= event.date %></h3>
<ul>
<% end %>
<li><%= link_to event %></li>
<% if next_event && next_event.date != event.date
# end the nested list and make way for the next date header and set of events
%>
</ul>
</li>
<% end %>
Что происходит в вызове render
, который мы передаем во всей коллекции @events
какместный житель под названием events
.Затем внутри партиала мы используем автоматически сгенерированный метод event_counter
для поиска предыдущих (events[event_counter - 1]
) и следующих (events[event_counter + 1]
) событий в коллекции.Затем, если дата текущего event
отличается от даты last_event
(имеется в виду, что она является первой для этой даты), мы начинаем новый набор с новым заголовком даты, и если дата event
отличаетсяс даты next_event
(т. е. она является последней на эту дату), мы заканчиваем набор.
Это немного некрасиво, и есть более элегантные способы сделать это наверняка, но это устраивает работусделано.