Adding :collection and :new options to load_resource method so we can specify behavior of additional actions if needed.

This commit is contained in:
Ryan Bates 2009-12-13 10:42:10 -08:00
parent a5f98824a0
commit 63634b4f5d
4 changed files with 55 additions and 3 deletions

View File

@ -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. * 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) 0.2.1 (Nov 26, 2009)

View File

@ -28,7 +28,23 @@ module CanCan
# end # end
# #
# See load_and_authorize_resource to automatically authorize the resource too. # 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 } before_filter { |c| ResourceAuthorization.new(c, c.params, *args).load_resource }
end end

View File

@ -2,9 +2,10 @@ module CanCan
class ResourceAuthorization # :nodoc: class ResourceAuthorization # :nodoc:
attr_reader :params attr_reader :params
def initialize(controller, params) def initialize(controller, params, options = {})
@controller = controller @controller = controller
@params = params @params = params
@options = options
end end
def load_and_authorize_resource def load_and_authorize_resource
@ -13,7 +14,13 @@ module CanCan
end end
def load_resource 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 end
def authorize_resource def authorize_resource
@ -37,5 +44,13 @@ module CanCan
def model_instance=(instance) def model_instance=(instance)
@controller.instance_variable_set("@#{model_name}", instance) @controller.instance_variable_set("@#{model_name}", instance)
end end
def collection_actions
[:index] + [@options[:collection]].flatten
end
def new_actions
[:new, :create] + [@options[:new]].flatten
end
end end
end end

View File

@ -63,4 +63,23 @@ describe CanCan::ResourceAuthorization do
mock(authorization).authorize_resource mock(authorization).authorize_resource
authorization.load_and_authorize_resource authorization.load_and_authorize_resource
end 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 end