Question

I'm having a difficult time grasping polymorphic associations in Rails. I have two models, Group and User.

A User needs to belong to a group, but a Group can have_many users AND have_many groups. I need my groups to be like a tree, which I think the Ancestry gem should help, but I haven't tried yet.

Seems like I would need some kind of join model, Membership, that has a user_id and a group_id. Then I could do a has_many :through to relate users to groups, but how would I get it to have many groups as well? Would the Membership be the polymorphic model?

Thanks!

Andy

Was it helpful?

Solution

This is not a polymorphic association. A polymorphic association is an association that transcends class types, such as a image class belonging to people and dogs class.

You are talking about Single Table Inheritance where Groups can belong to another group and have other groups. Something like what is below is what you are looking for.

This is just air code, might need some tweaks

class User
  belongs_to :group
end

class Group
  has_many :users
  has_many :sub_groups, :class => "Group", :foreign_key => :parent_group_id
  belongs_to :parent_group, :class => "Group", :foreign_key => :parent_group_id
end

OTHER TIPS

Yes, you've basically got it. Your Membership model would need the following fields:

group_id
member_id
member_type

group_id is the Group the "member" belongs to. member_id would be the id of a Person or Group, and member_type would be 'Person' or 'Group'.

Membership would have the following association:

class Member < ActiveRecord::Base
  belongs_to :member, :polymorphic => true
end

Then your User and Group classes would have something like

has_many :memberships, :as => :member

Check this link out: Rails model relationships. I found it very helpful in nailing down the various relationships rails supports easily and well.

EDIT: fixed URL. sorry.

I think Ancestry is the right answer. I've used a much older one, acts_as_tree, and it was helpful. Starting a new project now I'd use Ancestry. You can do it without that as other answers have suggested but you won't get all the free methods Ancestry gives you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top