roleful icon indicating copy to clipboard operation
roleful copied to clipboard

Generic roles for you and your objects

h1. Role-ful

Roles for you and your objects.

Like it? Then please "recommend me on Working with Rails":http://www.workingwithrails.com/person/7973-pat-nakajima.

h3. Usage

In your class, after including @Roleful@, declare your roles. It's up to you to implement a @role@ instance method for your objects that determines what kind of permissions they receive.

If an object doesn't have a @role@ method, or if the @role@ returns an invalid role, the @:null@ role will be used, which just returns false for all permissions.

h4. Example Class:

class User
  include Roleful
  
  def initialize(name=nil)
    @role = name
  end
  
  def role
    @role
  end
end

h3. Basic permissions

The @role@ class method allows you to declare permissions for a given role:

class User
  
  role :admin do
    can :view_all_files
    can :view_all_pages
  end
  
  role :paid do
    can :view_all_pages
    can :view_invoice
  end
  
end

gets you:

User.new.null? # => true
User.new.can?(:view_invoice) # => false
User.new.can_view_all_pages? # => false
User.new.can_view_all_files? # => false

User.new(:paid).paid? # => true
User.new(:paid).can?(:view_invoice) # => true
User.new(:paid).can_view_all_pages? # => true
User.new(:paid).can_view_all_files? # => false

User.new(:admin).admin? # => true
User.new(:admin).can?(:view_invoice) # => false
User.new(:admin).can_view_all_pages? # => true
User.new(:admin).can_view_all_files? # => true

h3. Super-users

If you pass @role@ the @:superuser@ option, then objects with that role will be considered super-users, meaning every permission declared for that class will be available:

class User
  
  role :super_admin, :superuser => true
  
end
User.new(:super_admin).can_view_all_pages? # => true
User.new(:super_admin).can_view_all_files # => true
User.new(:super_admin).can?(:view_invoice) # => true

h3. Declaring permissions for more than one role

Sometimes you want to add the same permission to multiple roles. To do this, simply pass multiple role names when calling @role@, and each of the roles will be granted the permissions declared in the block.

Alternatively, you can just pass @:all@ to @role@, and all of your roles besides the @:null@ role will be granted the permissions declared in the block.

class User
  role :foo, :bar do
    can :be_both
  end
  
  role :all do
    can :pay_the_billz
  end
end
User.new(:foo).can_be_both? # => true
User.new(:bar).can_be_both? # => true
User.new(:admin).can_be_both? # => false

User.new(:foo).can_pay_the_billz? # => true
User.new(:bar).can_pay_the_billz? # => true
User.new(:admin).can_pay_the_billz? # => true

# The :null role still returns false
User.new(:null).can_pay_the_billz? # => false

h3. Objects with more than one role

If an object's @role@ returns an @Array@, then the object will be granted all of the roles in that @Array@.

class User
  role :foo do
    can :be_foo
  end
  
  role :bar do
    can :be_bar
  end
end
user = User.new([:foo, :bar])

user.foo? # => true
user.bar? # => true

user.can_be_foo? # => true
user.can_be_bar? # => true

h3. Advanced Permissions

Sometimes a permission is contingent upon some other conditions being met. You can handle these situations by passing the @can@ call a block. This block will be called in the context of your object:

class User
  role :thinker do
    can :be_self do |that|
      self == that
    end
  end
end
me  = User.new(:thinker)
you = User.new(:thinker)

me.can_be_self?(me) # => true
me.can_be_self?(you) # => false

h3. Role contexts

If you want to temporarily give an object a role, you can use the @with_role@ method:

class User
  role :admin do
    can :do_anything
  end
end
user = User.new

user.admin? # => false
user.can_do_anything? # => false

user.with_role(:admin) do
  user.admin? # => true
  user.can_do_anything? # => true
end

user.admin? # => false
user.can_do_anything? # => false

h3. Install

Install roleful like so:

gem install nakajima-roleful --source=http://gems.github.com

"View the CI build":http://ci.patnakajima.com/nakajima-roleful

@(c) Copyright 2008 Pat Nakajima, released under the MIT license@