permissable
Permissable creates the ability to add a permissions system to “resources” based on a “member”. It allows you to define a member using the permissable
method:
class User < ActiveRecord::Base has_permissions_for [:section, :category], :to => [:read, :write, :moderate] end
Permissable uses a single “permissions” table (and subsuquently a Permission model), with a polymorphic relationship between both the member and the resource.
Important to know… This is my first attempt at a RubyGem. I’m using the gem itself for an application currently in development, so you can be assured at least the basic functionality should work as it goes along. For the time being, I’m not writing any tests, but there will be some later.
I decided to develop it because I couldn’t find anything that achieved the same thing that didn’t seem cumbersome or akward to configure.
This documention is incomplete… I’ll add more later.
Usage
class User < ActiveRecord::Base has_permissions_for [:section, :category], :to => [:read, :write, :moderate] end
The permissable method accepts two options:
-
method: The permission you want to assign (read, write, moderate, etc)
-
options: A hash of options.
The only required option is the :to key, which defines a number of permisssions to assign to the speficied resource(s)
Setting Permissions via Association
Permissable also allows you to specify permissions via an association. For instance say your User has_many roles, and you would like the permissions to be based on a particular user’s roles. To do this, add the :through option when setting permissions:
:through => :roles When permissable does permission lookups on any of the resources specified in has_permissions_for it will use the assocation to define them. Instead of looking up User.permissions, it will now lookup user.roles.permissions.
Always allowing specific members
If you would like can? to always pass for a particular member, use the :allow_with option with has_permissions_for. The allow_with option accepts a method name within your member model that will be called prior to checking permissions from the database.
class User < ActiveRecord::Base has_permissions_for [:section, :category], :to => [:read, :write, :moderate], :allow_with => :is_admin?
def is_admin? // your logic here. If this resolves to true… can? will also be true. end end
Chaining Permissions
If you want your permissions to have a heirarchy, use the :chain option. For example, say you have three permission types: read, write, and moderate. In this instance, moderators should also be able to read and write a resource, and members who can write should also be able to read the resource. To do this, add this chain when calling has_permissions_for:
class User < ActiveRecord::Base has_permissions_for [:resource], :to => [:read, :write, :moderate], :chain => { :moderate => [:read, :write], :write => [:read] } end Now calling can?(:read, @resource) will evaluate to true when permissions exist for reading or writing, and can?(:read, @resource) will evaluate to true when permissions exist at least to write.
Planned Updates
In the near future there are plans to add the ability to “eager_load” permissions on a user the first time it is created. When using this configuration option, ALL permissions relating to that user are looked up in a single database query, and then cached to the user instance. By default I think this may be the proper way to handle it anyway.
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
Copyright © 2010 kurb media, llc. See LICENSE for details.