diff --git a/README.md b/README.md index 6bc6b6e..05a54f9 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ Canard ====== [![Build Status](https://travis-ci.org/james2m/canard.svg?branch=master)](https://travis-ci.org/james2m/canard) -Canard brings CanCan and RoleModel together to make role based authorization in Rails easy. Your ability +Canard brings CanCan and RoleModel together to make role-based authorization in Rails easy. Your ability definitions gain their own folder and a little structure. The easiest way to get started is with the Canard generator. Canard progressively enhances the abilities of the model by applying role abilities on -top of the models base abilities. +top of the model's base abilities. A User model with :admin and :manager roles would be defined: class User < ActiveRecord::Base @@ -14,32 +14,31 @@ A User model with :admin and :manager roles would be defined: end -If a User has both the :manager and :admin roles Canard will apply the abilities in the following order. -First it will look for a users abilities, then it will look for the roles in the order they are defined e.g. +If a User has both the :manager and :admin roles, Canard looks first for user abilities. Then it will look for other roles in the order that they are defined: app/abilities/users.rb app/abilities/manager.rb app/abilities/admin.rb -Therefore each the later abilities only need to build on their predecessors. +Therefore each of the later abilities can build on its predecessor. Usage ===== -To generate some abilities for the User. +To generate some abilities for the User: $ rails g canard:ability user can:[read,create]:[account,statement] cannot:destroy:account create app/abilities/users.rb invoke rspec create spec/abilities/user_spec.rb -Generates an ability folder in Rails root and an associated spec; +This action generates an ability folder in Rails root and an associated spec: app.abilities/ users.rb spec/abilities/ users_spec.rb -The resulting app/abilities/users.rb will look something like this; +The resulting app/abilities/users.rb will look something like this: Canard::Abilities.for(:user) do @@ -49,7 +48,7 @@ The resulting app/abilities/users.rb will look something like this; end -And it's associated test spec/abilities/users_spec.rb; +And its associated test spec/abilities/users_spec.rb will look something like this: require_relative '../spec_helper' require "cancan/matchers" @@ -89,7 +88,7 @@ And it's associated test spec/abilities/users_spec.rb; end -You can also re-use abilities defined for one role in another. This allows you to 'inherit' abilities without having to assign all of the roles to the user. To do this, pass a list of role names to the includes_abilities_of method +You can also re-use abilities defined for one role in another. This allows you to 'inherit' abilities without having to assign all of the roles to the user. To do this, pass a list of role names to the includes_abilities_of method: Canard::Abilities.for(:writer) do @@ -112,48 +111,48 @@ You can also re-use abilities defined for one role in another. This allows you t end -A user assigned the :admin role will have all of the abilities of the :writer and :reviewer, along with their own abilities without having to have those individual roles assigned to them. +A user assigned the :admin role will have all of the abilities of the :writer and :reviewer, along with their own abilities, without having to have those individual roles assigned to them. -Now lets generate some abilities for the manager and admin. +Now let's generate some abilities for the manager and admin: $ rails g canard:ability admin can:manage:[account,statement] $ rails g canard:ability manager can:edit:statement -Gives us two new sets of abilities in the abilities folder. Canard will apply these abilities by first -loading the ability for the User model and then apply the abilities for each role the current user has. +This generates two new sets of abilities in the abilities folder. Canard will apply these abilities by first +loading the ability for the User model and then applying the abilities for each of the current user's roles. -If there is no user (i.e. logged out) Canard creates a guest and looks for a guest ability to apply so: +If there is no user (i.e. logged out), Canard creates a guest and looks for a guest ability to apply: $ rails g canard:ability guest can:create:user -Would generate an ability for a not logged in user to signup. +This would generate a signup ability for a user who was not logged in. -Obviously the generators are just a starting point and should be used only to get you going. I strongly -suggest that every new model you create you add to the abilities as the specs are easy to write and CanCan +Obviously the generators are just a starting point and should be used only to get you going. I strongly +suggest that you add each new model to the abilities because the specs are easy to write and CanCan definitions are very clear and simple. Scopes ====== -The :acts_as_user method with automatically define some named scopes for each role. For the example User model -above it will define the following scopes; +The :acts_as_user method will automatically define some named scopes for each role. For the User model +above it will define the following scopes: -User.admins:: return all the users with the admin role -User.non_admins:: return all the users without the admin role -User.managers:: return all the users with the manager role -User.non_managers:: return all the users without the manager role +`User.admins::` return all the users with the admin role +`User.non_admins::` return all the users without the admin role +`User.managers::` return all the users with the manager role +`User.non_managers::` return all the users without the manager role -In addition to the role specific scopes it also adds some general scopes; +In addition to the role specific scopes it also adds some general scopes: -User.with_any_role(roles):: return all the users with any of the specified roles -User.with_all_roles(roles):: return only the users with all the specified roles +`User.with_any_role(roles)::` return all the users with any of the specified roles +`User.with_all_roles(roles)::` return only the users with all the specified roles Installation ============ Rails 3.x, 4.x & 5.x -------------------- -Add the canard gem to your Gemfile. In Gemfile: +Add the canard gem to your Gemfile: gem "canard" @@ -167,20 +166,20 @@ That's it! Rails 2.x --------- -Sorry you are out of luck with Rails 2.x Canard has only been written and tested with Rails 3 and above. +Sorry, you are out of luck. Canard has only been written and tested with Rails 3 and above. -Supported ORM's +Supported ORMs --------------- Canard is ORM agnostic. ActiveRecord and Mongoid (thanks David Butler) adapters are currently implemented. -New adapters can easily be added, but you'd need to check CanCan can also support your adapter. +New adapters can easily be added, but you'd need to check to see if CanCan can also support your adapter. Further reading --------------- -Canard stands on the sholders of Ryan Bates' CanCan and Martin Rehfeld's RoleModel. You can read more +Canard stands on the shoulders of Ryan Bates' CanCan and Martin Rehfeld's RoleModel. You can read more about defining abilities on the CanCan wiki (https://github.com/ryanb/cancan/wiki). Canard implements -the Ability class for you so you don't need the boilerplate code from Ryan's example; +the Ability class for you so you don't need the boilerplate code from Ryan's example: class Ability include CanCan::Ability @@ -195,13 +194,13 @@ the Ability class for you so you don't need the boilerplate code from Ryan's exa end end -The Canard equivalent for non admins would be; +The Canard equivalent for non-admins would be: Canard::Abilities.for(:user) do can :read, :all end -And for Admins; +And for admins: Canard::Abilities.for(:admin) do can :manage, :all @@ -217,8 +216,8 @@ Note on Patches/Pull Request * Fork the project. * Make your feature addition or bug fix. * Add tests for it (when I have some). 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 it when I pull) +* 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 so I can ignore it when I pull.) * Send me a pull request. Bonus points for topic branches. Contributors