0

I have a loop through a hash of times with a nested Booking class. I want it to make a table of times from the hash and say "Available" or "Booked" if there is a booking object with the same hour Time as the value of the hash.

index.html.erb

table
<%  @times.each_with_index do |(key, value), index| %>
tr
<td><%= key %></td>

  <% for booking in @bookings %>
    <% if booking.time.strftime("%H").to_s == value.to_s then %>
     <td> <em> Booked </em> </td>
    <% end %> 
  <% end %>

  <% if booking.time.strftime("%H").to_s != value.to_s then %>
  <td> <em> Available </em> </td>
  <% end %> 
/tr
<% end %>
/table

This produces this:

9am     Available
10am    Available
11am    Available 
12am    Available
1pm     Booked  Available
2pm     Available
3pm     Available
4pm     Booked
5pm     Available
6pm     Available
7pm     Available
8pm     Available
9pm     Available 

So it is repeating the loop on 1pm because that value has change the second time round. How can I avoid this happening?

3 Answers 3

2

@Chowletts answer seems to do what you want, but I can't stand the idea of doing unnecessary calculations inside the loop when it is not necessary. So here's my solution:

<%  
    booking_times = @bookings.map{ |booking| booking.time.hour }
    @times.each_with_index do |(key, value), index| 
%>
  tr
    <td><%= key %></td>
    <td><em><%= booking_times.include?(value.to_i) ? "Booked" : "Available" %></em></td>
  /tr
<% end %>
Sign up to request clarification or add additional context in comments.

2 Comments

for more fastest search you can use hash: booking_hash = @bookings.each_with_object({}) {|i, a| a[i.time.hour] = i } usage: booking_hash[value.to_i]?
Cool!, that would be even better.
1

The problem is that you effectively display "Available" if the last booking doesn't match this time. You could use a flag, which you set if you find a booking:

<table>
<%  @times.each_with_index do |(key, value), index| %>
<tr>
<td><%= key %></td>
  <% booked = false %>
  <% for booking in @bookings %>
    <% if booking.time.strftime("%H").to_s == value.to_s then %>
     <td> <em> Booked </em> </td>
     <% booked = true %>
    <% end %> 
  <% end %>

  <% if !booked %>
  <td> <em> Available </em> </td>
  <% end %> 
</tr>
<% end %>
</table>

Alternatively, if you set up a has_one (or whatever) relationship between Time and Booking, you could just check if the time has a booking associated with it.

Comments

1

More simple way:

table
<%  @times.each_with_index do |(key, value), index| %>
tr
<td><%= key %></td>

  <% if @bookings.index{|booking| booking.time.strftime("%H").to_s == value.to_s}  then %>
    <td> <em> Booked </em> </td>
  <% else %>
    <td> <em> Available </em> </td>
  <% end %> 

/tr
<% end %>
/table

Comments

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.