Created
April 5, 2012 11:55
-
-
Save sj26/2310315 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
class User < ActiveRecord::Base | |
attr_accessible :name | |
has_many :admin_memberships, class_name: "Membership", conditions: {role: 'admin'} | |
has_many :editor_memberships, class_name: "Membership", conditions: {role: 'editor'} | |
def admin? | |
admin_memberships.exists? | |
end | |
def editor? | |
editor_memberships.exists? | |
end | |
end | |
class Group < ActiveRecord::Base | |
attr_accessible :name | |
has_many :admin_memberships, class_name: "Membership", conditions: {role: "admin"} | |
has_many :editor_memberships, class_name: "Membership", conditions: {role: "editor"} | |
has_many :admins, through: :admin_memberships, source: :user | |
has_many :editors, through: :editor_memberships, source: :user | |
end | |
class Membership < ActiveRecord::Base | |
attr_accessible :role | |
belongs_to :user | |
belongs_to :group | |
end | |
sam = User.new name: "Sam" | |
# => #<User id: 1, name: "Sam", created_at: "2012-04-05 11:45:54", updated_at: "2012-04-05 11:45:54"> | |
rainbows = Group.new name: "Rainbows" | |
# => #<Group id: 1, name: "Rainbows", created_at: "2012-04-05 11:46:06", updated_at: "2012-04-05 11:46:06"> | |
rainbows.admins << sam | |
# => [#<User id: 1, name: "Sam", created_at: "2012-04-05 11:45:54", updated_at: "2012-04-05 11:45:54">] | |
rainbows.admin_memberships | |
# => [#<Membership id: 2, user_id: 1, group_id: 1, role: "admin", created_at: "2012-04-05 11:48:58", updated_at: "2012-04-05 11:48:58">] | |
user.admin? | |
# Membership Exists (0.3ms) SELECT 1 FROM "memberships" WHERE "memberships"."user_id" = 1 AND "memberships"."role" = 'admin' LIMIT 1 | |
# => true |
Very nice. Note that the conditions
syntax is very different in Rails 4
http://guides.rubyonrails.org/association_basics.html#the-has-many-association
And if you (like me) are tempted to use Rails 4.1 enums, the syntax is a bit more interesting pending the outcome of these:
rails/rails#13918
rails/rails#13433
In my case, I have the role
in the Membership
table (so Users
can have a different role per Group
) and here is what I'm using in gem 'rails', '4.1.0.beta1'
class Group
has_many :admins, -> { where role: Membership::ROLE[:admin] }, class_name: 'Membership'
Here is the enum declaration
enum role: {
reader: 10,
editor: 20,
admin: 30
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You just helped me a great deal to simplify my code (from ~10 lines of very cluttered and ununderstandable
has_many
definitions to 2 very clean lines).But I have a question where you can maybe help: would it be possible to set the
role
attribute also when callingbuild
on thehas_many
relation?I would like to be able to do this: