Skip to content

Instantly share code, notes, and snippets.

@tomafro
Created June 23, 2009 09:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomafro/134455 to your computer and use it in GitHub Desktop.
Save tomafro/134455 to your computer and use it in GitHub Desktop.
class Account < ActiveRecord::Base
end
class AccountRole < ActiveRecord::Base
belongs_to :account
belongs_to :target, :polymorphic => true
end
module Tomafro::Extensions::HasRole
def has_role(role)
singular_role = role.to_s.singularize
plural_role = singular_role.to_s.pluralize
unless reflect_on_association("account_roles")
has_many "account_roles", :as => "target", :class_name => "AccountRole"
end
has_many "#{singular_role}_roles", :as => "target", :class_name => "AccountRole", :conditions => {:role => role}
has_many plural_role, :through => "#{singular_role}_roles", :source => "account" do
def add(account)
# If any role has been granted, we update it to reflect the current role, otherwise we create a new role
through_conditions = proxy_reflection.through_reflection.options[:conditions]
if existing = proxy_owner.account_roles.first(:conditions => {:account_id => account.id})
proxy_owner.send("#{existing.role}_roles").reset
existing.update_attributes(through_conditions)
else
proxy_owner.account_roles.create!({:account => account}.merge(through_conditions))
end
reset
end
def remove(account)
through_conditions = proxy_reflection.through_reflection.options[:conditions]
if existing = proxy_owner.account_roles.first(:conditions => {:account_id => account.id}.merge(through_conditions))
existing.destroy
reset
end
end
end
end
def has_roles(*roles)
roles.each do |role|
has_role role
end
end
ActiveRecord::Base.extend self
end
class Project < ActiveRecord::Base
has_roles 'viewer', 'member', 'admin'
end
project = Project.create!
tom = Account.create! :name => 'tom'
luke = Account.create! :name => 'luke'
project.admins.add(tom)
project.admins
# => [<tom>]
project.admins.remove(tom)
project.admins
# => []
project.admins.add(luke)
project.admins.add(tom)
project.viewers.add(tom)
project.admins
# => [<luke>]
project.viewers
# => [<tom>]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment