Skip to content
Browse files

turning load and authorize resource methods into class methods which …

…set up the before filter so they can accept additional arguments
  • Loading branch information...
1 parent 43947c8 commit a5f98824a050dfe8174d4131f51126873a24e36e @ryanb committed Dec 13, 2009
View
2 CHANGELOG.rdoc
@@ -1,3 +1,5 @@
+* BACKWARDS INCOMPATIBLE: turning load and authorize resource methods into class methods which set up the before filter so they can accept additional arguments.
+
0.2.1 (Nov 26, 2009)
* many internal refactorings - see issues #11 and #12
View
91 lib/cancan/controller_additions.rb
@@ -3,7 +3,56 @@ module CanCan
# This module is automatically included into all controllers.
# It also makes the "can?" and "cannot?" methods available to all views.
module ControllerAdditions
+ module ClassMethods
+ # Sets up a before filter which loads and authorizes the current resource. This accepts the
+ # same arguments as load_resource and authorize_resource. See those methods for details.
+ #
+ # class BooksController < ApplicationController
+ # load_and_authorize_resource
+ # end
+ #
+ def load_and_authorize_resource(*args)
+ before_filter { |c| ResourceAuthorization.new(c, c.params, *args).load_and_authorize_resource }
+ end
+
+ # Sets up a before filter which loads the appropriate model resource into an instance variable.
+ # For example, given an ArticlesController it will load the current article into the @article
+ # instance variable. It does this by either calling Article.find(params[:id]) or
+ # Article.new(params[:article]) depending upon the action. It does nothing for the "index"
+ # action.
+ #
+ # You would call this method directly on the controller class.
+ #
+ # class BooksController < ApplicationController
+ # load_resource
+ # end
+ #
+ # See load_and_authorize_resource to automatically authorize the resource too.
+ def load_resource(*args) # TODO add documentation for options which can be passed.
+ before_filter { |c| ResourceAuthorization.new(c, c.params, *args).load_resource }
+ end
+
+ # Sets up a before filter which authorizes the current resource using the instance variable.
+ # For example, if you have an ArticlesController it will check the @article instance variable
+ # and ensure the user can perform the current action on it. Under the hood it is doing
+ # something like the following.
+ #
+ # unauthorized! if cannot?(params[:action].to_sym, @article || Article)
+ #
+ # You would call this method directly on the controller class.
+ #
+ # class BooksController < ApplicationController
+ # authorize_resource
+ # end
+ #
+ # See load_and_authorize_resource to automatically load the resource too.
+ def authorize_resource(*args)
+ before_filter { |c| ResourceAuthorization.new(c, c.params, *args).authorize_resource }
+ end
+ end
+
def self.included(base)
+ base.extend ClassMethods
base.helper_method :can?, :cannot?
end
@@ -70,48 +119,6 @@ def can?(*args)
def cannot?(*args)
(@current_ability ||= current_ability).cannot?(*args)
end
-
- # This method loads the appropriate model resource into an instance variable. For example,
- # given an ArticlesController it will load the current article into the @article instance
- # variable. It does this by either calling Article.find(params[:id]) or
- # Article.new(params[:article]) depending upon the action. It does nothing for the "index"
- # action.
- #
- # You would often use this as a before filter in the controller. See
- # load_and_authorize_resource to handle authorization too.
- #
- # before_filter :load_resource
- #
- def load_resource
- ResourceAuthorization.new(self, params).load_resource
- end
-
- # Authorizes the resource in the current instance variable. For example,
- # if you have an ArticlesController it will check the @article instance variable
- # and ensure the user can perform the current action on it.
- # Under the hood it is doing something like the following.
- #
- # unauthorized! if cannot?(params[:action].to_sym, @article || Article)
- #
- # You would often use this as a before filter in the controller.
- #
- # before_filter :authorize_resource
- #
- # See load_and_authorize_resource to automatically load the resource too.
- def authorize_resource
- ResourceAuthorization.new(self, params).authorize_resource
- end
-
- # Calls load_resource to load the current resource model into an instance variable.
- # Then calls authorize_resource to ensure the current user is authorized to access the page.
- # You would often use this as a before filter in the controller.
- #
- # before_filter :load_and_authorize_resource
- #
- def load_and_authorize_resource
- load_resource
- authorize_resource
- end
end
end
View
22 spec/cancan/controller_additions_spec.rb
@@ -27,19 +27,21 @@
@controller.cannot?(:foo, :bar).should be_true
end
- it "should load resource" do
- mock.instance_of(CanCan::ResourceAuthorization).load_resource
- @controller.load_resource
+ it "load_and_authorize_resource should setup a before filter which passes call to ResourceAuthorization" do
+ stub(CanCan::ResourceAuthorization).new(@controller, @controller.params, :foo => :bar).mock!.load_and_authorize_resource
+ mock(@controller_class).before_filter { |block| block.call(@controller) }
+ @controller_class.load_and_authorize_resource :foo => :bar
end
- it "should authorize resource" do
- mock.instance_of(CanCan::ResourceAuthorization).authorize_resource
- @controller.authorize_resource
+ it "authorize_resource should setup a before filter which passes call to ResourceAuthorization" do
+ stub(CanCan::ResourceAuthorization).new(@controller, @controller.params, :foo => :bar).mock!.authorize_resource
+ mock(@controller_class).before_filter { |block| block.call(@controller) }
+ @controller_class.authorize_resource :foo => :bar
end
- it "should load and authorize resource in one call through controller" do
- mock(@controller).load_resource
- mock(@controller).authorize_resource
- @controller.load_and_authorize_resource
+ it "load_resource should setup a before filter which passes call to ResourceAuthorization" do
+ stub(CanCan::ResourceAuthorization).new(@controller, @controller.params, :foo => :bar).mock!.load_resource
+ mock(@controller_class).before_filter { |block| block.call(@controller) }
+ @controller_class.load_resource :foo => :bar
end
end
View
7 spec/cancan/resource_authorization_spec.rb
@@ -56,4 +56,11 @@
authorization.authorize_resource
}.should raise_error(CanCan::AccessDenied)
end
+
+ it "should call load_resource and authorize_resource for load_and_authorize_resource" do
+ authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "show")
+ mock(authorization).load_resource
+ mock(authorization).authorize_resource
+ authorization.load_and_authorize_resource
+ end
end

0 comments on commit a5f9882

Please sign in to comment.
Something went wrong with that request. Please try again.