From 021f33c9a0bf2f9a60ba1b4f19b5d21a0f25b7ca Mon Sep 17 00:00:00 2001 From: Ryan Bates Date: Mon, 14 Dec 2009 08:31:49 -0800 Subject: [PATCH] Adding :class option to load_resource so one can customize which class to use for the model - closes #17 --- CHANGELOG.rdoc | 2 ++ lib/cancan/controller_additions.rb | 8 +++++++- lib/cancan/controller_resource.rb | 5 +++-- lib/cancan/resource_authorization.rb | 2 +- spec/cancan/controller_resource_spec.rb | 6 ++++++ spec/cancan/resource_authorization_spec.rb | 7 +++++++ 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index 636bce8..370faf1 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -1,3 +1,5 @@ +* Adding :class option to load_resource so one can customize which class to use for the model - see issue #17 + * Don't fetch parent of nested resource if *_id parameter is missing so it works with shallow nested routes - see issue #14 diff --git a/lib/cancan/controller_additions.rb b/lib/cancan/controller_additions.rb index 0a7b5a7..92695a6 100644 --- a/lib/cancan/controller_additions.rb +++ b/lib/cancan/controller_additions.rb @@ -59,6 +59,9 @@ module CanCan # # load_resource :nested => [:publisher, :author] # + # [:+class+] + # The class to use for the model. + # # [:+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+ @@ -72,7 +75,7 @@ module CanCan # fetch one. # # load_resource :new => :build - # + # def load_resource(options = {}) before_filter(options.slice(:only, :except)) { |c| ResourceAuthorization.new(c, c.params, options.except(:only, :except)).load_resource } end @@ -99,6 +102,9 @@ module CanCan # [:+except+] # Does not apply before filter to given actions. # + # [:+class+] + # The class to use for the model. + # def authorize_resource(options = {}) before_filter(options.slice(:only, :except)) { |c| ResourceAuthorization.new(c, c.params, options.except(:only, :except)).authorize_resource } end diff --git a/lib/cancan/controller_resource.rb b/lib/cancan/controller_resource.rb index d057f35..a14475a 100644 --- a/lib/cancan/controller_resource.rb +++ b/lib/cancan/controller_resource.rb @@ -1,13 +1,14 @@ module CanCan class ControllerResource # :nodoc: - def initialize(controller, name, parent = nil) + def initialize(controller, name, parent = nil, options = {}) @controller = controller @name = name @parent = parent + @options = options end def model_class - @name.to_s.camelize.constantize + @options[:class] || @name.to_s.camelize.constantize end def find(id) diff --git a/lib/cancan/resource_authorization.rb b/lib/cancan/resource_authorization.rb index f64ebbd..1ae67f9 100644 --- a/lib/cancan/resource_authorization.rb +++ b/lib/cancan/resource_authorization.rb @@ -30,7 +30,7 @@ module CanCan private def resource - @resource ||= ControllerResource.new(@controller, model_name, parent_resource) + @resource ||= ControllerResource.new(@controller, model_name, parent_resource, @options) end def parent_resource diff --git a/spec/cancan/controller_resource_spec.rb b/spec/cancan/controller_resource_spec.rb index 40e77d0..89b07f9 100644 --- a/spec/cancan/controller_resource_spec.rb +++ b/spec/cancan/controller_resource_spec.rb @@ -40,4 +40,10 @@ describe CanCan::ControllerResource do CanCan::ControllerResource.new(@controller, :ability).find(123) @controller.instance_variable_get(:@ability).should == :some_ability end + + it "should use the model class option if provided" do + stub(Person).find(123) { :some_resource } + CanCan::ControllerResource.new(@controller, :ability, nil, :class => Person).find(123) + @controller.instance_variable_get(:@ability).should == :some_resource + end end diff --git a/spec/cancan/resource_authorization_spec.rb b/spec/cancan/resource_authorization_spec.rb index 2ed5928..d2cdf3a 100644 --- a/spec/cancan/resource_authorization_spec.rb +++ b/spec/cancan/resource_authorization_spec.rb @@ -105,4 +105,11 @@ describe CanCan::ResourceAuthorization do @controller.instance_variable_get(:@person).should == :some_person @controller.instance_variable_get(:@ability).should == :some_ability end + + it "should load the model using a custom class" do + stub(Person).find(123) { :some_resource } + authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "show", :id => 123}, {:class => Person}) + authorization.load_resource + @controller.instance_variable_get(:@ability).should == :some_resource + end end