# Simple role system through associative table

**URL:** <https://www.ruby-forum.com/t/simple-role-system-through-associative-table/186682>\
**Category:** Rails\
**Created:** [April 11, 2010, 12:02pm UTC](https://www.ruby-forum.com/t/simple-role-system-through-associative-table/186682 "2010-04-11T12:02:16Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![gattone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/898d66/32.png) [@gattone](https://www.ruby-forum.com/u/gattone)\
**Post date:** [April 11, 2010, 12:02pm UTC](https://www.ruby-forum.com/t/simple-role-system-through-associative-table/186682/1 "2010-04-11T12:02:16Z")

</div>

So I have the Ninja model which has many Hovercrafts through  
ninja\_hovercrafts (which stores the ninja\_id and the hovercraft\_id).

It is of my understanding that this kind of arrangement should be set  
in a way that the associative table stores only enough information to  
bind two different classes.

But I’d like to use the associative table to work as a very  
streamlined authorization hub on my application. So i’d also like this  
table to inform my system if this binding makes the ninja the pilot or  
co-pilot of a given hovercraft, through a “role” field in the table.

My questions are:

Is this ugly?

Is this normal?

Are there methods built into rails that would help me to automagically  
create Ninjas and Hovercrafts associations WITH the role? For exemple,  
could I have a nested form to create both ninjas and hcs in a way that  
the role field in ninjas\_hovercrafts would be also filled?

If managing my application roles this way isn’t a good idea, whats the  
non-resource heavy alternative (my app is being designed trying to  
avoid scalability problems such as excessive joins, includes, etc)

thank you

---

<div class="post-metadata">

**Author:** ![gattone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/898d66/32.png) [@gattone](https://www.ruby-forum.com/u/gattone)\
**Post date:** [April 12, 2010, 10:01pm UTC](https://www.ruby-forum.com/t/simple-role-system-through-associative-table/186682/2 "2010-04-12T22:01:12Z")

</div>

Daniel,

Adding attributes to the HMT model is an acceptable practice.  
Originally  
HABTM was used for many-to-many relationships and it assumed a simple  
table  
in the middle with the related ids. The problem was that the  
relationship  
table often needed to become a model of its own with additional  
attributes.  
This is why HMT came about and is the preferred method for many-to-many  
relationships.

I am not aware of a way to create all three models with the role in the  
field as you described. I believe you will have to code that in the  
controller.

If you do something like this and the association will set the role  
value  
for you…

class Pilot \< ActiveRecord::Base  
belongs\_to :ninja  
belongs\_to :hovercraft  
end

class Hovercraft \< ActiveRecord::Base  
has\_many :pilots  
has\_many :piloted, :conditions =\> {:role =\> ‘pilot’}, :class\_name =\>  
“Pilot”  
has\_many :copiloted, :conditions =\> {:role =\> ‘co-pilot’}, :class\_name  
=\>  
“Pilot”

has\_many :ninjas, :through =\> :pilots  
has\_many :copilot\_ninjas, :through =\> :copiloted, :source =\> :ninja  
has\_many :pilot\_ninjas, :through =\> :piloted, :source =\> :ninja  
end

class Ninja \< ActiveRecord::Base  
has\_many :pilots  
has\_many :piloted, :conditions =\> {:role =\> ‘pilot’}, :class\_name =\>  
“Pilot”  
has\_many :copiloted, :conditions =\> {:role =\> ‘co-pilot’}, :class\_name  
=\>  
“Pilot”

has\_many :hovercrafts, :through =\> :pilots  
has\_many :copiloted\_hovercrafts, :through =\> :copiloted, :source =\>  
:hovercraft  
has\_many :piloted\_hovercrafts, :through =\> :piloted, :source =\>  
:hovercraft  
end

Then you can do stuff like this…

# Create hovercraft

hovercraft = …

# Create pilot ninja

pilot\_ninja = …

# Create co-pilot ninja

copilot\_ninja = …

# Associate ninjas to hovercrafts

hovercraft.piloted.create(:ninja =\> pilot\_ninja)  
hovercraft.copiloted.create(:ninja =\> copilot\_ninja)

Anthony C.

> **[Commonthread](https://commonthread.com)**
>
> Instantly connect and build rapport with anyone you meet, in person or online.
