Reputation: 191
I've looked everywhere and have been unable to find exactly what I'm looking for. I have an idea of what I need, but am unable to put 2 and 2 together.
This code isn't proper, but this is the idea:
class Group < ActiveRecord::Base
has_one :owner, :class_name => "user"
has_many :members, :class_name => "user"
end
class User < ActiveRecord::Base
belongs_to :groups
has_one :group, :class_name "user"
end
I believe I need a has_many :through association, but am unsure about how to implement it. How do I build my models/controllers/migrations in order to represent the association within the parameters above?
Upvotes: 2
Views: 1016
Reputation: 356
I would suggest as well using a join table as follows:
class Membership < ActiveRecord::Base
belongs_to :group
belongs_to :user
end
class Group < ActiveRecord::Base
belongs_to :owner, class_name: "User"
has_many :members, through: :memberships, source: :user
has_many :memberships
end
class User < ActiveRecord::Base
has_one :owned_group, foreign_key: "owner_id", class_name: "Group"
has_many :groups, through: :memberships
has_many :memberships
end
Migrations are as follows:
class CreateMemberships < ActiveRecord::Migration
def change
create_table :memberships do |t|
t.references :user
t.references :group
t.timestamps null: false
end
end
end
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.timestamps null: false
end
end
end
class CreateGroups < ActiveRecord::Migration
def change
create_table :groups do |t|
t.references :owner
t.timestamps null: false
end
end
end
Upvotes: 2
Reputation: 2812
Modern Rails applications use has_many through:
instead of HABTM.
class User < ActiveRecord::Base
has_many :groups, through: :user_groups
end
class Group < ActiveRecord::Base
has_one :owner, through: :user_groups, source: :user
has_many :members, through: :user_groups, source: :user
end
class UserGroups < ActiveRecord::Base
validates :owner, uniqueness: true
belongs_to :member, class_name: 'User'
belongs_to :group
belongs_to :owner, class_name: 'User'
end
Adding source
on has_many
and has_one
allows you to write Group.find(id).members
and Group.find(id).owner
. Validate the uniqueness of a group owner on the join.
Upvotes: 2
Reputation: 294
http://guides.rubyonrails.org/association_basics.html#the-types-of-associations
The main types you could use in this case and depend on your requirements are
has_many :groups, through: join_table
where the join table would reference both the user and the group by having user_id and group_id. This allows you to have additional information related to the group membership, maybe you want a join date or a membership id or something like that.
has_and_belongs_to_many :groups
which is implemented in a similar fashion but bypassess the join model and would simply give you a list of groups/users on either side of the relationship
Polymorphic relationships wouldn't really come into play unless you were planning on having maybe different types of memberships, maybe groups, or organizations or something that would require similar, but separate database tables.
Upvotes: 1