adding 'cannot?' method which performs opposite check of 'can?' - closes #1

This commit is contained in:
Ryan Bates 2009-11-17 10:46:16 -08:00
parent df276536ab
commit 0f49b5478f
6 changed files with 27 additions and 8 deletions

View File

@ -1,3 +1,5 @@
* adding "cannot?" method to ability, controller, and view which is inverse of "can?" - see issue #1
* BACKWARDS INCOMPATIBLE: use Ability#initialize instead of 'prepare' to set up abilities - see issue #4
*0.1.0* (Nov 16th, 2009)

View File

@ -38,17 +38,17 @@ First define a class called Ability, place it in "models/ability.rb".
This class is where all permissions will go. See the "Defining Abilities" section below for more information.
In the view layer you can access the current permissions at any point using the "can?" method. See "Checking Abilities" section below.
In the view layer you can access the current permissions at any point using the "can?" and "cannot?" methods. See "Checking Abilities" section below.
<% if can? :update, @article %>
<%= link_to "Edit", edit_article_path(@article) %>
<% end %>
You can also use this method in the controller layer along with the "unauthorized!" method to restrict access.
You can also use these methods in the controller layer along with the "unauthorized!" method to restrict access.
def show
@article = Article.find(params[:id])
unauthorized! unless can? :read, @article
unauthorized! if cannot? :read, @article
end
Setting this for every action can be tedious, therefore a before filter is also provided for automatically applying this setting to a RESTful style resource controller.
@ -135,6 +135,10 @@ You can also pass the class instead of an instance (if you don't have one handy)
<%= link_to "New Project", new_project_path %>
<% end %>
The "cannot?" method is for convenience and performs the opposite check of "can?"
cannot? :destroy, @project
== Custom Actions
@ -148,7 +152,7 @@ There is no limit to what actions you can use to determine abilities. For exampl
# projects_controller.rb
def update
unauthorized! if params[:project][:upload_picture] && !can?(:upload_picture, @project)
unauthorized! if params[:project][:upload_picture] && cannot?(:upload_picture, @project)
# ...
end
@ -199,7 +203,7 @@ def test "user can only destroy projects which he owns"
user = User.new
ability = Ability.new(user)
assert ability.can?(:destroy, Project.new(:user => user))
assert !ability.can?(:destroy, Project.new)
assert ability.cannot?(:destroy, Project.new)
end

View File

@ -21,6 +21,10 @@ module CanCan
false
end
def cannot?(*args)
!can?(*args)
end
def possible_actions_for(initial_action)
actions = [initial_action]
(@aliased_actions || default_alias_actions).each do |target, aliases|

View File

@ -1,7 +1,7 @@
module CanCan
module ControllerAdditions
def self.included(base)
base.helper_method :can?
base.helper_method :can?, :cannot?
end
def unauthorized!
@ -16,6 +16,10 @@ module CanCan
(@current_ability ||= current_ability).can?(*args)
end
def cannot?(*args)
(@current_ability ||= current_ability).cannot?(*args)
end
def load_resource # TODO this could use some refactoring
unless params[:action] == "index"
if params[:id]

View File

@ -81,4 +81,8 @@ describe CanCan::Ability do
it "should not respond to prepare (now using initialize)" do
@ability.should_not respond_to(:prepare)
end
it "should offer cannot? method which is simply invert of can?" do
@ability.cannot?(:tie, String).should be_true
end
end

View File

@ -11,7 +11,7 @@ describe CanCan::ControllerAdditions do
before(:each) do
@controller_class = Class.new
@controller = @controller_class.new
mock(@controller_class).helper_method(:can?)
mock(@controller_class).helper_method(:can?, :cannot?)
@controller_class.send(:include, CanCan::ControllerAdditions)
end
@ -26,10 +26,11 @@ describe CanCan::ControllerAdditions do
@controller.current_ability.should be_kind_of(Ability)
end
it "should provide a can? method which goes through the current ability" do
it "should provide a can? and cannot? methods which go through the current ability" do
stub(@controller).current_user { :current_user }
@controller.current_ability.should be_kind_of(Ability)
@controller.can?(:foo, :bar).should be_false
@controller.cannot?(:foo, :bar).should be_true
end
it "should load the resource if params[:id] is specified" do