Created
March 6, 2011 17:21
-
-
Save tbeauvais/857422 to your computer and use it in GitHub Desktop.
Rails Group/User relationship using join table - has_many :users, :through => :members
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################# | |
# Migration file to create index so you don't get duplicate users for a group | |
############################################################################# | |
class AddMembersUniquenessIndex < ActiveRecord::Migration | |
def self.up | |
add_index :group_members, [:group_id,:user_id], :unique => true | |
end | |
def self.down | |
remove_index :group_members, [:group_id,:user_id] | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Users and Groups that were previously manually created..... | |
# Here's a dump of them: | |
ruby-1.9.2-p0 > Group.all | |
=> [#<Group id: 1, name: "Group 1", description: "Group One", created_at: "2011-02-27 18:55:01", updated_at: "2011-02-27 18:55:01">, | |
#<Group id: 2, name: "Group 2", description: "Group Two", created_at: "2011-02-27 18:55:39", updated_at: "2011-02-27 18:55:39">] | |
ruby-1.9.2-p0 > User.all | |
=> [#<User id: 1, name: "User 1", email: "user1@test.com", created_at: "2011-02-27 18:39:58", updated_at: "2011-02-27 18:39:58">, | |
#<User id: 2, name: "User 2", email: "user2@test.com", created_at: "2011-02-27 18:40:20", updated_at: "2011-02-27 18:40:20">] | |
# Get the first Group | |
ruby-1.9.2-p0 > g = Group.first | |
=> #<Group id: 1, name: "Group 1", description: "Group One", created_at: "2011-02-27 18:55:01", updated_at: "2011-02-27 18:55:01"> | |
# List its current Users which is none | |
ruby-1.9.2-p0 > g.users | |
=> [] | |
#################################################################################################################### | |
# Add association of existing Group and User through the Group members join table | |
#################################################################################################################### | |
ruby-1.9.2-p0 > u = g.members.build(:user_id => 1) | |
=> #<Member id: nil, user_id: 1, group_id: 1, created_at: nil, updated_at: nil> | |
# Save the Member | |
ruby-1.9.2-p0 > u.save | |
=> true | |
# Reload the Group | |
ruby-1.9.2-p0 > g = Group.first | |
=> #<Group id: 1, name: "Group 1", description: "Group One", created_at: "2011-02-27 18:55:01", updated_at: "2011-02-27 18:55:01"> | |
# List its current Users which is one | |
ruby-1.9.2-p0 > g.users | |
=> [#<User id: 1, name: "User 1", email: "user1@test.com", created_at: "2011-02-27 18:39:58", updated_at: "2011-02-27 18:39:58">] | |
#################################################################################################################### | |
# Here's a way to create a new User and add to Group through the members join table. Note save not called | |
#################################################################################################################### | |
ruby-1.9.2-p0 > u = g.users.create(:name => "User 3", :email => "user3@test.com") | |
=> #<User id: 3, name: "User 3", email: "user3@test.com", created_at: "2011-02-27 20:35:37", updated_at: "2011-02-27 20:35:37"> | |
ruby-1.9.2-p0 > g.users | |
=> [#<User id: 1, name: "User 1", email: "user1@test.com", created_at: "2011-02-27 18:39:58", updated_at: "2011-02-27 18:39:58">, #<User id: 3, name: "User 3", email: "user3@test.com", created_at: "2011-02-27 20:35:37", updated_at: "2011-02-27 20:35:37">] | |
ruby-1.9.2-p0 > | |
#################################################################################################################### | |
# Create a new User and add to Group through the members join table. Note you must save the Group to update users and members tables | |
#################################################################################################################### | |
ruby-1.9.2-p0 > u = g.users.build(:name => "User 4", :email => "user4@test.com") | |
=> #<User id: nil, name: "User 4", email: "user4@test.com", created_at: nil, updated_at: nil> | |
ruby-1.9.2-p0 > g.save | |
=> true | |
#################################################################################################################### | |
# Destroy of User also removes Groups member relationship (User - has_many :group_members, :dependent => :destroy) | |
#################################################################################################################### | |
# Current list of Users for specified Group | |
ruby-1.9.2-p0 > g = Group.first | |
ruby-1.9.2-p0 > g.users | |
=> [#<User id: 1, name: "User 1", email: "user1@test.com", created_at: "2011-02-27 18:39:58", updated_at: "2011-02-27 18:39:58">, | |
#<User id: 3, name: "User 3", email: "user3@test.com", created_at: "2011-02-27 20:35:37", updated_at: "2011-02-27 20:35:37">, | |
#<User id: 4, name: "User 4", email: "user4@test.com", created_at: "2011-02-27 20:39:08", updated_at: "2011-02-27 20:39:08">] | |
# Find and destroy user | |
ruby-1.9.2-p0 > u = User.find(4) | |
ruby-1.9.2-p0 > u.destroy | |
# View updated Group/User relationship | |
ruby-1.9.2-p0 > g = Group.first | |
=> #<Group id: 1, name: "Group 1", description: "Group One", created_at: "2011-02-27 18:55:01", updated_at: "2011-02-27 18:55:01"> | |
ruby-1.9.2-p0 > g.users | |
=> [#<User id: 1, name: "User 1", email: "user1@test.com", created_at: "2011-02-27 18:39:58", updated_at: "2011-02-27 18:39:58">, | |
#<User id: 3, name: "User 3", email: "user3@test.com", created_at: "2011-02-27 20:35:37", updated_at: "2011-02-27 20:35:37">] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# == Schema Information | |
# | |
# Table name: groups | |
# | |
# id :integer not null, primary key | |
# name :string(255) | |
# description :string(255) | |
# created_at :datetime | |
# updated_at :datetime | |
# | |
class Group < ActiveRecord::Base | |
# destroy the relationship if group is deleted | |
has_many :members, :dependent => :destroy | |
# has many through members join table | |
has_many :users, :through => :members | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# == Schema Information | |
# | |
# Table name: members | |
# | |
# id :integer not null, primary key | |
# user_id :integer | |
# group_id :integer | |
# created_at :datetime | |
# updated_at :datetime | |
# | |
class Member < ActiveRecord::Base | |
belongs_to :group | |
belongs_to :user | |
validates :user_id, :presence => true | |
validates :group_id, :presence => true | |
# avoid in memory duplicates. You will also need add unique index to db | |
validates :user_id, :uniqueness => {:scope => [:user_id, :group_id]} | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# == Schema Information | |
# | |
# Table name: users | |
# | |
# id :integer not null, primary key | |
# name :string(255) | |
# email :string(255) | |
# created_at :datetime | |
# updated_at :datetime | |
# | |
class User < ActiveRecord::Base | |
# destroy the user in the members list if the user is deleted | |
has_many :members, :dependent => :destroy | |
# has many through members join table | |
has_many :groups, :through => :members | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment