user4227507
user4227507

Reputation:

Ruby on Rails only show data value once if there are more than one of the same

In my ruby on rails application I am currently displaying the date and time each film is shown through:

<% if not @film.showings.blank? %>
    To book click on a time below:</br>
    <% @film.showings.each do |showing| %>
        <%= showing.show_date.strftime("%A %e %B %Y") %>@ <%= showing.show_time.strftime("%H:%M") %><br>            
    <% end %>
<% else %>
    <p>There are currently no showings for this film.</p>
<% end %>

And this displays data like the following:

Sunday 25 January 2015 @ 12:00
Sunday 25 January 2015 @ 16:00
Monday 26 January 2015 @ 11:00
Monday 26 January 2015 @ 22:00
Tuesday 27 January 2015 @ 22:00
Wednesday 28 January 2015 @ 11:00
Wednesday 28 January 2015 @ 12:00
Wednesday 28 January 2015 @ 16:00
Wednesday 28 January 2015 @ 19:30

But what I want to be able to do is if the date is repeated then it only shows it once and repeats the time, so for example the date Sunday 25 January 2015 would be shown as:

Sunday 25 January 2015 @ 12:00 16:00

Upvotes: 0

Views: 905

Answers (3)

Rich Seviora
Rich Seviora

Reputation: 1809

Given an array of datetime objects, you can use the following code to extract a nested hash of date and time showings. It probably best lives inside your Film model.

def showings_hash
  showings.pluck(:show_time).map {|datetime| datetime.to_date}.uniq.map{|date| {date => dates.select{|datetime| date == datetime.to_date}}}
end

This returns:

- 2015-01-12:
  - !ruby/object:DateTime 2015-01-12 18:00:00.000000000 Z
  - !ruby/object:DateTime 2015-01-12 19:00:00.000000000 Z
  - !ruby/object:DateTime 2015-01-12 20:00:00.000000000 Z
- 2015-01-13:
  - !ruby/object:DateTime 2015-01-13 20:00:00.000000000 Z

You can then iterate through each showing date in the view like so:

<% @film.showings_hash.each do |showing_date| %>
  <li>
    <%= showing_date %>
    <% showing_date.each do |showtime| %>
      <%= showtime.strftime("%H:%M") %>
    <% end %>
  </li>
<% end %>

Upvotes: 0

Alex Peachey
Alex Peachey

Reputation: 4686

You could place a function like this in helpers or a decorator if you are using them. I'm assuming you pass in the showings from @file.showings. This will return an array that is how you want that you could loop over in the view and display.

def show_times(showings)
  showings.each_with_object({}) do |showing, hash|
    key = showing.show_date.strftime("%A %e %B %Y")
    hash[key] ||= []
    hash[key] << showing.show_time.strftime("%H:%M")
  end.map do |date, times|
    "#{date} @ #{times.join(' ')}"
  end
end

Upvotes: 0

East2d
East2d

Reputation: 2096

You should group records by date and join hours.

<% if not @film.showings.blank? %>
To book click on a time below:</br>
<% @film.showings.group_by{|showing| showing.show_date.strftime("%A %e %B %Y") }.to_a.each do |showing| %>
    <%= showing.first %>@ <%= showing.last.map{|s| s.show_time.strftime("%H:%M")}.join(' ')  %><br>            
<% end %>
<% else %>
    <p>There are currently no showings for this film.</p>
<% end %>

Upvotes: 1

Related Questions