BACKWARDS INCOMPATIBLE: use Ability#initialize instead of 'prepare' to set up abilities - closes #4

This commit is contained in:
Ryan Bates 2009-11-17 10:25:47 -08:00
parent 9d58226563
commit 1edf583110
6 changed files with 17 additions and 20 deletions

View File

@ -1,3 +1,5 @@
* BACKWARDS INCOMPATIBLE: use Ability#initialize instead of 'prepare' to set up abilities - see issue #4
*0.1.0* (Nov 16th, 2009) *0.1.0* (Nov 16th, 2009)
* initial release * initial release

View File

@ -2,7 +2,7 @@
This is a simple authorization solution for Rails which is completely decoupled from how you set up the user's roles. All permissions are stored in a single location for convenience. This is a simple authorization solution for Rails which is completely decoupled from how you set up the user's roles. All permissions are stored in a single location for convenience.
This assumes you already have an authentication solution (such as Authlogic) which proves a current_user model. This assumes you already have an authentication solution (such as Authlogic) which provides a current_user model.
== Installation == Installation
@ -27,7 +27,7 @@ First define a class called Ability, place it in "models/ability.rb".
class Ability class Ability
include CanCan::Ability include CanCan::Ability
def prepare(user) def initialize(user)
if user.admin? if user.admin?
can :manage, :all can :manage, :all
else else
@ -77,7 +77,7 @@ If the user authorization fails, a CanCan::AccessDenied exception will be raised
== Defining Abilities == Defining Abilities
As shown above, the Ability#prepare method is where all user permissions are defined. The user model is passed into this method so you are free to modify the permissions based on the user's attributes. This way CanCan is completely decoupled with how you choose to handle roles. As shown above, the Ability#initialize method is where all user permissions are defined. The user model is passed into this method so you are free to modify the permissions based on the user's attributes. This way CanCan is completely decoupled with how you choose to handle roles.
The "can" method accepts two arguments, the first one is the action you're setting the permission for, the second one is the class of object you're setting it on. The "can" method accepts two arguments, the first one is the action you're setting the permission for, the second one is the class of object you're setting it on.
@ -153,19 +153,17 @@ There is no limit to what actions you can use to determine abilities. For exampl
end end
== Customizing Assumptions == Assumptions & Configuring
CanCan makes two assumptions about your application. CanCan makes two assumptions about your application.
* The permissions are defined in Ability#prepare. * The permissions are defined in Ability#initialize.
* The user is fetched with current_user method in the controller. * The user is fetched with the current_user method in the controller.
You can override these by defining the "current_ability" method in your ApplicationController. You can override these by defining the "current_ability" method in your ApplicationController.
def current_ability def current_ability
ability = UserAbility.new # instead of Ability UserAbility.new(current_account) # instead of Ability.new(current_user)
ability.prepare(current_account) # instead of current_user
ability # be sure to return the ability
end end
That's it! That's it!
@ -180,7 +178,7 @@ For example, let's assume that each user has_many :permissions, and each permiss
class Ability class Ability
include CanCan::Ability include CanCan::Ability
def prepare(user) def initialize(user)
can :manage, :all do |action, object_class, object| can :manage, :all do |action, object_class, object|
user.permissions.find_all_by_action(action).any? do |permission| user.permissions.find_all_by_action(action).any? do |permission|
permission.object_type.constantize == object_class && permission.object_type.constantize == object_class &&

View File

@ -47,9 +47,5 @@ module CanCan
:update => [:edit], :update => [:edit],
} }
end end
def prepare(user)
# to be overriden by included class
end
end end
end end

View File

@ -9,9 +9,7 @@ module CanCan
end end
def current_ability def current_ability
ability = ::Ability.new ::Ability.new(current_user)
ability.prepare(current_user)
ability
end end
def can?(*args) def can?(*args)
@ -43,4 +41,4 @@ if defined? ActionController
ActionController::Base.class_eval do ActionController::Base.class_eval do
include CanCan::ControllerAdditions include CanCan::ControllerAdditions
end end
end end

View File

@ -78,7 +78,7 @@ describe CanCan::Ability do
@ability.can?(:edit, 123).should == :update_called @ability.can?(:edit, 123).should == :update_called
end end
it "should respond to prepare" do it "should not respond to prepare (now using initialize)" do
@ability.should respond_to(:prepare) @ability.should_not respond_to(:prepare)
end end
end end

View File

@ -2,6 +2,9 @@ require File.dirname(__FILE__) + '/../spec_helper'
class Ability class Ability
include CanCan::Ability include CanCan::Ability
def initialize(user)
end
end end
describe CanCan::ControllerAdditions do describe CanCan::ControllerAdditions do