Permalink
Browse files

Adding :collection and :new options to load_resource method so we can…

… specify behavior of additional actions if needed.
  • Loading branch information...
1 parent a5f9882 commit 63634b4f5dd727a4bde505f8f066bb23a326b633 @ryanb committed Dec 13, 2009
View
@@ -1,3 +1,5 @@
+* Adding :collection and :new options to load_resource method so we can specify behavior of additional actions if needed.
+
* 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)
@@ -28,7 +28,23 @@ def load_and_authorize_resource(*args)
# 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.
+ #
+ # Options:
+ # [:+collection+]
+ # Specify which actions are resource collection actions in addition to :+index+. This
+ # is usually not necessary because it will try to guess depending on if an :+id+
+ # is present in +params+.
+ #
+ # load_resource :collection => [:sort, :list]
+ #
+ # [:+new+]
+ # Specify which actions are new resource actions in addition to :+new+ and :+create+.
+ # Pass an action name into here if you would like to build a new resource instead of
+ # fetch one.
+ #
+ # load_resource :new => :build
+ #
+ def load_resource(*args)
before_filter { |c| ResourceAuthorization.new(c, c.params, *args).load_resource }
end
@@ -2,9 +2,10 @@ module CanCan
class ResourceAuthorization # :nodoc:
attr_reader :params
- def initialize(controller, params)
+ def initialize(controller, params, options = {})
@controller = controller
@params = params
+ @options = options
end
def load_and_authorize_resource
@@ -13,7 +14,13 @@ def load_and_authorize_resource
end
def load_resource
- self.model_instance = params[:id] ? model_class.find(params[:id]) : model_class.new(params[model_name.to_sym]) unless params[:action] == "index"
+ unless collection_actions.include? params[:action].to_sym
+ if new_actions.include? params[:action].to_sym
+ self.model_instance = model_class.new(params[model_name.to_sym])
+ else
+ self.model_instance = model_class.find(params[:id]) if params[:id]
+ end
+ end
end
def authorize_resource
@@ -37,5 +44,13 @@ def model_instance
def model_instance=(instance)
@controller.instance_variable_set("@#{model_name}", instance)
end
+
+ def collection_actions
+ [:index] + [@options[:collection]].flatten
+ end
+
+ def new_actions
+ [:new, :create] + [@options[:new]].flatten
+ end
end
end
@@ -63,4 +63,23 @@
mock(authorization).authorize_resource
authorization.load_and_authorize_resource
end
+
+ it "should not build a resource when on custom collection action" do
+ authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "sort"}, {:collection => [:sort, :list]})
+ authorization.load_resource
+ @controller.instance_variable_get(:@ability).should be_nil
+ end
+
+ it "should build a resource when on custom new action even when params[:id] exists" do
+ stub(Ability).new(nil) { :some_resource }
+ authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "build", :id => 123}, {:new => :build})
+ authorization.load_resource
+ @controller.instance_variable_get(:@ability).should == :some_resource
+ end
+
+ it "should not try to load resource for other action if params[:id] is undefined" do
+ authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "list"})
+ authorization.load_resource
+ @controller.instance_variable_get(:@ability).should be_nil
+ end
end

0 comments on commit 63634b4

Please sign in to comment.