a project manger type of application, staff are assigned to projects,
but each staff has varied roles for different projects… STI does not
seem to be applicable here
Imagine a table staffs…
id int
name varchar
blah…
is_manager int 1
is_engineer int 1
is_producer int 1
and projects…
id
name
manager_id
engineer_id
producer_id
how is the best way to subclass manager, engineer, and producer from
class:staff??
I dealt with a similar problem recently and ended up creating one AR
table with a series of boolean flags to indicate if the object was a
member of a particular child class. Just like your example I wanted
the ability for child objects from different classes to inherit from
a single parent class.
Here is a rough idea of what I did:
class Staff < ActiveRecod::Base
connected to the one table where all data is stored
add one boolean column for each subclass
end
class Manager < Staff
def initialize(attributes = nil)
# set is_manager to true for all new objects
super(:is_manager => true)
self.attributes = attributes unless attributes.nil?
end
class << self
def find(*args)
self.with_scope(:find => {:conditions =>
[“staff.is_manager=?”,true]}) do
super
end
end
end
end
Then just repeat the above for your engineer and producer classes.
There are some problems with this approach. The rails paginator
still counts the number of records in the base class. I think this
can be solved by overriding the method that determines the number of
records. Another problem is that the scoped find does not catch
calls to the various find convenience methods that rails provides.
I am very interested to hear how other people have solved this problem.
a project manger type of application, staff are assigned to projects,
but each staff has varied roles for different projects… STI does not
seem to be applicable here
Seems to me you’ve solved your own question.
Staff (or “people”) is a many-many with projects, with the join table
also acting as a role identifier. Since your join here has attributes
of its own (the role), probably a has_many :through makes more sense.
Something along the lines of:
class Person < AR
has_many :projects, :through => roles
…
It might get interesting if you allow a person to have MULTIPLE roles
on a project though.