# Model class as join table

**URL:** <https://www.ruby-forum.com/t/model-class-as-join-table/90991>\
**Category:** Rails\
**Created:** [April 3, 2007, 5:25pm UTC](https://www.ruby-forum.com/t/model-class-as-join-table/90991 "2007-04-03T17:25:32Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rod](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/50afbb/32.png) [@Rod](https://www.ruby-forum.com/u/Rod)\
**Post date:** [April 3, 2007, 5:25pm UTC](https://www.ruby-forum.com/t/model-class-as-join-table/90991/1 "2007-04-03T17:25:32Z")

</div>

I’m a Ruby noob, and I’m pretty convinced there’s an elegant way to  
implement what I’m trying to do. I thought I’d ask if there’s any  
idioms I could use.

Two classes: “team” and “member” joined in a team\_members table. In  
addition to the IDs, the team\_members group has a “permissions”  
column. The permission can take three values: creator, participant or  
observer.

The Member model has three collections: created\_teams, ,  
participating\_teams, and observed\_teams. I use the following  
construction (this is only the observers collection, but it’s the same  
for the other two.)

has\_many :member\_teams  
has\_many :observed\_teams,  
:through =\> :member\_teams,  
:source =\> :teams,  
:conditions =\> "member\_teams.permissions = ‘#{Observer}’

Works like a charm and I love it. Here’s my question.

I’d like to set the permissions field on the member\_teams table when I  
assign it to a collection. For example,

t = Team.new  
member.participating\_teams \<\< t

That does insert a record in the join table, but I have to access the  
join record manually and set the permission, otherwise it’s null. I’d  
like it to be set to “participant” in the instance above, or  
“observer” if added to the observed\_teams collection, etc.

Is there a Ruby Way?

---

<div class="post-metadata">

**Author:** ![Rod](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/50afbb/32.png) [@Rod](https://www.ruby-forum.com/u/Rod)\
**Post date:** [April 3, 2007, 7:14pm UTC](https://www.ruby-forum.com/t/model-class-as-join-table/90991/2 "2007-04-03T19:14:45Z")

</div>

Whups, accidental post. Darn touchpads.

Anyhow, I accomplished it as below (some class names have changed, I’m  
sure you can get it though) but it seems tres ugly. If there’s a  
better way I’m all ears.

Thanks,  
Rod

---

<div class="post-metadata">

**Author:** ![Rod](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/50afbb/32.png) [@Rod](https://www.ruby-forum.com/u/Rod)\
**Post date:** [April 3, 2007, 7:11pm UTC](https://www.ruby-forum.com/t/model-class-as-join-table/90991/3 "2007-04-03T19:11:45Z")

</div>

In case anybody hits this in a search, I accomplished this via the  
“after\_save” method of the model.

def after\_save  
user\_resources.each do |ur|  
if !ur.user\_type  
if observers.detect {|user| user.id == ur.user\_id }  
ur.user\_type = User::Observer  
ur.save!  
elsif participants.detect {|user| user.id == ur.user\_id }  
ur.user\_type = User::Participant  
ur.save!  
elsif creators.detect {|user| user.id == ur.user\_id }  
ur.user\_type = User::Creator  
ur.save!  
end  
end  
end  
end
