Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Generic role model strategies sharing same API easy to insert in any model

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.


Generic Role strategies

Generic role strategies that share the same API and are easy to insert in any existing User model. Comes with a Rails 3 generator to instantly configure your Rails 3 app with a Role strategy of choice.

I have developed the following roles gems for popular ORMs that all support the same roles generic API.

Feel free to roll your own ORM extension for your favorite ORM!

Status update (12 sept, 2010)

Roles generic has now been refactored in order to tidy up the code base and make it even more generic, flexible and easy to extend. It should now work! Please let me know if you have any issues ;)


gem install roles_generic


The library comes with the following role models built-in:

Inline roles (in User model):

  • admin_flag (Boolean flag - 'admin' or not)
  • role_string (String)
  • roles_string (Comma separated String - note: no role name must have a comma in its name!)
  • role_strings (Set of Strings)
  • roles_mask (Integer mask)

Using separate Role model:

  • one_role (relation to a Role model instance)
  • many_roles(Set of Role relationships)

Note: The following examples use RSpec to demonstrate usage scenarios.

Examples of configuring for the other strategies can be found on the wiki pages.

Example : admin_flag

Creates and uses a binary field 'admin_flag', which when true signals that this user is an administrator and otherwise a normal user.

  class User
    include Roles::Generic 

    attr_accessor :name, :admin_flag 

    role_strategy :admin_flag, :default

    roles :admin, :user

    def initialize name, *new_roles = name
      self.roles = new_roles

Example: Using an ORM

Data Mapper with persistent attributes :name and :admin_flag

  class User
    include Roles::Generic 
    include DataMapper::Resource

    property :name, Boolean
    property :admin_flag, Boolean

    role_strategy :admin_flag, :default

    roles :admin, :user

    def initialize name, *new_roles = name
      self.roles = new_roles

Note: I recommend using s specific ORM roles gem such as roles_data_mapper instead. But this approach might be a good starting point for developing a roles gem for an ORM that is not supported ;)

Role API

Instance methods

Has ALL of the given roles been assigned?

  • has_roles?(*roles) - alias: is?

Has ANY (at least ONE) of the given roles been assigned?

  • has_role? *roles - alias: has?

Is this a valid role? (can the role be found in list of valid roles?)

  • valid_role? role

Is this user the admin user (and user has no other roles)

  • admin? - short for - is?(:admin)

Class methods

  • roles - list of valid roles
  • roles_attribute - get the attribute where the role is stored on the user
  • roles_attribute= - set the role(s) attribute

Usage of API

  before :each do
    @admin_user = 'Admin user', :admin
    @guest = 'Guest', :guest

  it "user 'Admin user' should have role :admin" do

    @admin_user.role.should   == :admin
    @admin_user.roles.should  == [:admin]      
    @admin_user.admin?.should be_true

    @admin_user.has_role?   (:user).should be_false

    @admin_user.has_role?   (:admin).should be_true         (:admin).should be_true
    @admin_user.has_roles?  (:admin).should be_true
    @admin_user.has?        (:admin).should be_true      


  it "user Guest should have role :guest" do
    @guest.roles.should == [:guest]
    @guest.admin?.should be_false

    @guest.has_role?  (:guest).should be_true    
    @guest.has_role?  (:admin).should be_false        (:admin).should be_false

    @guest.has_roles? (:guest).should be_true
    @guest.has?       (:admin).should be_false

  it "should set role of Guest user from :guest to :admin using roles=" do
    @guest.roles        = :admin      
    @guest.role.should == :admin           

    @guest.has_role?(:admin).should be_true      

Note on Patches/Pull Requests

  • Fork the project.
  • Make your feature addition or bug fix.
  • Add tests for it. This is important so I don't break it in a future version unintentionally.
  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
  • Send me a pull request. Bonus points for topic branches.


Copyright (c) 2010 Kristian Mandrup. See LICENSE for details.

Something went wrong with that request. Please try again.