Reputation: 1573
A Group
instance can contain Person
instances or other Group
instances. I want to use the Ancestry gem to mirror a hierarchy, but Ancestry does not seem to work with two different models. I don't want to use Single Table Inheritance on Person
and Model
because they are conceptually different.
What is the best way to go about modeling this requirement? I am willing to build my own hierarchy using many-to-many or other types of associations, but I am not sure how to make the two models (Person
and Group
) play nice with each other.
Thank you.
Upvotes: 2
Views: 786
Reputation: 9348
Sounds like you want to use a polymorphic association. See the rails guide for a simple example: http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
EDIT Update to include hierarchies:
Sounds like you need a couple new models, a "level" and "children" for example:
Group Model:
has_many :children, :as => :groupable
belongs_to :level
Person Model:
has_many :children, :as => :groupable
Level Model:
has_many :children
has_one :group
attr_accessible :level (integer)
Children Model:
belongs_to :groupable, :polymorphic => true
It may be possible to simplify this by combining the children and level model, but I don't know if ActiveRecord can handle two relationships between two tables (one for the group of children which are groups or people, and one for the parent, which sounds like it's always a group)
Your hierarchy level would be reflected by the level
integer in the level model.
Upvotes: 1
Reputation: 16435
You can easily set a hierarchy on the Group class (using whatever suits you for single-model hierarchies) and then add a one-to-many association between Groups and Users:
class Group < AR::Base
acts_as_tree # or whatever is called in your preferred tree implementation
has_many :users
end
class User < AR::Base
belongs_to :group
end
You will have
@group.children # => a list of groups
@group.parent # => another group or nil if root
@group.users # => the users directly below this group
@user.group # => a group
If you really need the group to have either users or subgroups but not both, use a validation rule.
Upvotes: 1