RoleModel is the framework agnostic, efficient and declarative way to do (user) roles. Assigned roles will be efficiently stored as a bitmask directly into your model within a configurable attribute.
It works like this:
# given a User class with a roles_mask attribute require 'rubygems' require 'role_model' class User attr_accessor :roles_mask # just for demo purposes # in real life this would usually be a persistent attribute, # e.g. if your User model is persisted in a SQL-DB add an integer # column named roles_mask to your users table -- just remove/replace # above attr_accessor line with whatever is needed for your # persistence solution include RoleModel # if you want to use a different integer attribute to store the # roles in, set it with roles_attribute :my_roles_attribute, # :roles_mask is the default name roles_attribute :roles_mask # declare the valid roles -- do not change the order if you add more # roles later, always append them at the end! # # Set dynamic: false to skip creating the dynamic methods for the roles. roles :admin, :manager, :author, prefix: "is_" end # # Test drive (check the RDoc or source for additional finesse) # >> u = User.new => #<User ...> # role assignment >> u.roles = [:admin] # ['admin'] works as well => [:admin] # adding roles >> u.roles << :manager >> u.roles.add(:manager) >> u.manager = true # if dynamic is enabled (by default) or... >> u.is_manager = true # If :prefix => "is_" => [:admin, :manager] # deleting roles >> u.roles.delete(:manager) >> u.manager = false # if dynamic is enabled (by default) or... >> u.is_manager = false # If :prefix => "is_" => [:admin] # querying roles... # get all valid roles that have been declared >> User.valid_roles => [:admin, :manager, :author] # ... retrieve all assigned roles >> u.roles # also: u.role_symbols for DeclarativeAuthorization compatibility => [:admin, :manager] # ... check for individual roles >> u.has_role? :author # has_role? is also aliased to is? => false # ... check for individual roles with dynamic methods (set dynamic: false to disable) >> u.author? # Or... >> u.is_author? # If :prefix => "is_" => false # ... check for multiple roles >> u.has_any_role? :author, :manager # has_any_role? is also aliased to is_any_of? => true >> u.has_all_roles? :author, :manager # has_all_roles? is also aliased to is? => false # see the internal bitmask representation (3 = 0b0011) >> u.roles_mask => 3 # see the role mask for certain role(s) >> User.mask_for :admin, :author => 5
Once you have included RoleModel, your model is perfectly fit to be used together with a role-based authorization solution, such as github.com/ryanb/cancan or github.com/stffn/declarative_authorization .
gem install role_model
Whenever I introduce a role-based authorization scheme into a project, the code gets coupled somehow to the available roles. So it usually does not make any sense to have a separate Role model stored within the database. This Role model will contain a predefined set of roles anyhow – changing that set will need to be reflected within the authorization code. Putting the available roles right into the model that actually uses them, makes things much easier and efficient.
-
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.
RoleModel is an implementation of the Role Based Authorization scheme proposed by Ryan Bates (wiki.github.com/ryanb/cancan/role-based-authorization).
Copyright © 2010 Martin Rehfeld. See LICENSE for details.