Simple role system through associative table

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

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.