meatherly
meatherly

Reputation: 1861

Many-to-many Users and groups, but groups have owners

I'm having trouble trying to understand/wrap my brain around this. I'm trying to create a relationship that allows this:

I've got the many-to-many relationship set up, but I can't seem to understand how to set up the ownership functionality.

here is what i have so far in my models:

    class Group < ActiveRecord::Base
      has_and_belongs_to_many :users
      attr_accessible :name, :description, :isPublic, :tag_list, :owner
    end

    class User < ActiveRecord::Base
      has_and_belongs_to_many :groups
      attr_accessible :name, :description, :owner_id
    end

Any help would be greatly appreciated!!

Upvotes: 7

Views: 4669

Answers (4)

nilay
nilay

Reputation: 365

In your user model add a boolean field as owner, so while creating user u can assign if he is the owner or not.
So if you want to check against the group u can do it as below.

group.users.each do |u|
u.owner?
// logic goes here
end

Upvotes: 0

beck03076
beck03076

Reputation: 3308

What about the link table approach?

Because, if you have a link table to users and groups as users_groups, then you can actually store another new attribute into that table during the moment of an user and group belonging to each other.

Like when, John the user belongs to boys the group, he is naughty. When John the user belongs to engineers the group, he is smart. So in the users_groups table, I can store something like below.

Users

id | Name
1 | John
2 | Steve

Groups

id | Name
1| boys
2| doctors
3| beggars

Users_Groups

user_id | group_id | info
1       | 1        | "naughty"
1       | 2        | "wearing white coat"
1       | 3        | "broke"
2       | 1        | "liar"

Isn't this fun?. But yeah, we have to work on the Has and belongs to many relationships. But just a thought!

JUST MENTIONED THE ADVANTAGE OF HAVING A LINK TABLE. IMPLEMENTATION of that is taken care by Sean Hill in his answer.

Upvotes: 0

Sean Hill
Sean Hill

Reputation: 15056

You can set it up a couple of ways:

1) Use a join model and place a flag on the join model that specifies that the group member is an owner.

class Group < ActiveRecord::Base
  has_many :memberships
  has_many :users, through: :memberships
  attr_accessible :name, :description, :isPublic, :tag_list, :owner
end

class Membership < ActiveRecord::Base
  belongs_to :group
  belongs_to :user

  #this table has a flag called owner and thus a method called owner?
end

class User < ActiveRecord::Base
  has_many :memberships
  has_many :groups, through: :memberships
  attr_accessible :name, :description, :owner_id
end

2) Keep your existing HABTM and add another join model for tracking ownership.

class Group < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_many :group_ownerships
  has_many :owners, through: :group_owernships, class_name: "User"
  attr_accessible :name, :description, :isPublic, :tag_list, :owner
end

class GroupOwnership < ActiveRecord::Base
  belongs_to :group
  belongs_to :user
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :groups
  has_many :group_ownerships
  has_many :owned_groups, through: :group_owernships, class_name: "Group"
  attr_accessible :name, :description, :owner_id
end

Upvotes: 14

pjam
pjam

Reputation: 6356

I think that one solution could be to define a new belongs_to relationship from the group to the owner. So you would need to add a new user_id column in the groups table.

class Group < ActiveRecord::Base
  has_and_belongs_to_many :users
  belongs_to :owner, class_name: 'User', foreign_key: 'user_id'
  attr_accessible :name, :description, :isPublic, :tag_list, :owner
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :groups
  has_many :owned_groups, class_name: 'Group', foreign_key: 'user_id'
  attr_accessible :name, :description, :owner_id
end

I think that's what you need. with a user, you can have all the groups he's a member of with user.groups, and you can have all the groups he owns user.owned_groups. With a group, you can have its owner : group.owner and all its members : group.users.

If you want to change the owner just do group.owner = new_user with new_user begin a User instance

Note that I quickly picked named for association and foreign keys, you could of course customize that.

Upvotes: 3

Related Questions