# HABTM Loops

**URL:** <https://www.ruby-forum.com/t/habtm-loops/113976>\
**Category:** Rails\
**Created:** [September 6, 2007, 8:35pm UTC](https://www.ruby-forum.com/t/habtm-loops/113976 "2007-09-06T20:35:56Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ebrad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/13edae/32.png) [@ebrad](https://www.ruby-forum.com/u/ebrad)\
**Post date:** [September 6, 2007, 8:35pm UTC](https://www.ruby-forum.com/t/habtm-loops/113976/1 "2007-09-06T20:35:56Z")

</div>

So, I have a “schedules” table and a “hours” table, joined by a  
“hours\_schedules” table. Think of the hours table as a category for  
when people will schedule themselves to work, which happens in weekly  
increments. At any given hour, there will be X number of people  
working. I need to represent each worker with an asterisk symbol in  
the weekly view. For example,

PEOPLE WORKING

# Sunday

12:00 am: \*\*  
1:00 am: \*\*\*\*\*  
2:00 am: \*\*\*\*\*\*  
3:00 am: \*\*\*\*\*\*  
etc…

How can I create a loop that can replace my extremely un-DRY queries  
in my controller?

# Controller

@contract1\_schedules = Hour.find(1).schedules.find(:all, :conditions  
=\> “week = ‘#{@woy}’”)  
@contract2\_schedules = Hour.find(2).schedules.find(:all, :conditions  
=\> “week = ‘#{@woy}’”)  
@contract3\_schedules = Hour.find(3).schedules.find(:all, :conditions  
=\> “week = ‘#{@woy}’”)  
@contract4\_schedules = Hour.find(4).schedules.find(:all, :conditions  
=\> “week = ‘#{@woy}’”)  
@contract5\_schedules = Hour.find(5).schedules.find(:all, :conditions  
=\> “week = ‘#{@woy}’”)  
etc…  
@contract168\_schedules =  
Hour.find(168).schedules.find(:all, :conditions =\> “week = ‘#{@woy}’”)

@woy is a calculated value for next week and is compared to the week  
number stored with the parent schedule so that I can display only a  
certain week at a time. Each of these queries represent a collection  
of schedules for that hour.

#################################

# View

# People Working

## Sunday

\<%= link\_to “12:00am”, :controller =\> “hours”, :action =\> ‘list’, :id  
=\> ‘1’ %\>:  
\<% for contract12\_schedule in @contract12\_schedules %\>  
\*  
\<% end %\>

\<%= link\_to “1:00am”, :controller =\> “hours”, :action =\> ‘list’, :id  
=\> ‘2’ %\>:  
\<% for contract1\_schedule in @contract1\_schedules %\>  
\*  
\<% end %\>

etc…  
#################################

---

<div class="post-metadata">

**Author:** ![ebrad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/13edae/32.png) [@ebrad](https://www.ruby-forum.com/u/ebrad)\
**Post date:** [September 6, 2007, 8:44pm UTC](https://www.ruby-forum.com/t/habtm-loops/113976/2 "2007-09-06T20:44:00Z")

</div>

# Schema

mysql\> show tables;  
±------------------------------+  
| Tables\_in\_sandbox\_development |  
±------------------------------+  
| contracts |  
| hours |  
| hours\_schedules |  
| schedules |  
| statuses |  
±------------------------------+

mysql\> describe schedules;  
±------------±-------------±-----±----±--------±---------------+  
| Field | Type | Null | Key | Default | Extra |  
±------------±-------------±-----±----±--------±---------------+  
| id | int(11) | NO | PRI | NULL | auto\_increment  
|  
| contract\_id | int(11) | YES | | NULL |  
|  
| week | int(11) | YES | | NULL |  
|  
| year | int(11) | YES | | NULL |  
|  
| name | varchar(255) | YES | | NULL |  
|  
±------------±-------------±-----±----±--------±---------------+  
5 rows in set (0.01 sec)

mysql\> describe hours;  
±------±-------------±-----±----±--------±------+  
| Field | Type | Null | Key | Default | Extra |  
±------±-------------±-----±----±--------±------+  
| id | int(11) | YES | | NULL | |  
| name | varchar(255) | YES | | NULL | |  
±------±-------------±-----±----±--------±------+  
2 rows in set (0.00 sec)

mysql\> describe hours\_schedules;  
±------------±--------±-----±----±--------±------+  
| Field | Type | Null | Key | Default | Extra |  
±------------±--------±-----±----±--------±------+  
| schedule\_id | int(11) | YES | | NULL | |  
| hour\_id | int(11) | YES | | NULL | |  
±------------±--------±-----±----±--------±------+  
2 rows in set (0.00 sec)

---

<div class="post-metadata">

**Author:** ![ebrad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/13edae/32.png) [@ebrad](https://www.ruby-forum.com/u/ebrad)\
**Post date:** [September 7, 2007, 4:03am UTC](https://www.ruby-forum.com/t/habtm-loops/113976/3 "2007-09-07T04:03:44Z")

</div>

It finally clicked for me…

# View

## Sunday

\<% for hour in @sunday\_hours %\>  
\<% @schedule\_hours =  
Hour.find(hour.id).schedules.find(:all, :conditions =\> “week =  
‘#{@woy}’”) %\>  
\<%= link\_to “#{hour.name}”, :controller =\> “hours”, :action =\>  
‘list’, :id =\> hour.id %\>:  
\<% for schedule in @schedule\_hours %\>  
\*  
\<% end %\>  
  
  
\<% end %\>

# Controller

def list  
# Finds next weeks beginning on Sunday  
@now = Time.now  
@next\_week = @now.next\_week - 1.day  
@woy = @next\_week\_date.cweek

```
# Creates an array of hours for each day of the week
@sunday_hours = Hour.find(:all, :conditions => "id > '0' AND id <

```

‘25’")  
@monday\_hours = Hour.find(:all, :conditions =\> “id \> ‘24’ AND id \<  
‘49’”)  
etc…  
end
