diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index c9ed045..c4078b2 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -1,3 +1,5 @@ +* Don't set resource instance variable if it has been set already - see issue #13 + * Allowing :nested option to accept an array for deep nesting * Adding :nested option to load resource method - see issue #10 diff --git a/lib/cancan/controller_additions.rb b/lib/cancan/controller_additions.rb index 85684bc..0a7b5a7 100644 --- a/lib/cancan/controller_additions.rb +++ b/lib/cancan/controller_additions.rb @@ -4,8 +4,8 @@ module CanCan # 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. + # Sets up a before filter which loads and authorizes the current resource. This performs both + # load_resource and authorize_resource and accepts the same arguments. See those methods for details. # # class BooksController < ApplicationController # load_and_authorize_resource @@ -21,12 +21,26 @@ module CanCan # 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. + # Call this method directly on the controller class. # # class BooksController < ApplicationController # load_resource # end # + # A resource is not loaded if the instance variable is already set. This makes it easy to override + # the behavior through a before_filter on certain actions. + # + # class BooksController < ApplicationController + # before_filter :find_book_by_permalink, :only => :show + # load_resource + # + # private + # + # def find_book_by_permalink + # @book = Book.find_by_permalink!(params[:id) + # end + # end + # # See load_and_authorize_resource to automatically authorize the resource too. # # Options: @@ -70,7 +84,7 @@ module CanCan # # unauthorized! if cannot?(params[:action].to_sym, @article || Article) # - # You would call this method directly on the controller class. + # Call this method directly on the controller class. # # class BooksController < ApplicationController # authorize_resource diff --git a/lib/cancan/controller_resource.rb b/lib/cancan/controller_resource.rb index 677acd0..d057f35 100644 --- a/lib/cancan/controller_resource.rb +++ b/lib/cancan/controller_resource.rb @@ -11,14 +11,14 @@ module CanCan end def find(id) - self.model_instance = base.find(id) + self.model_instance ||= base.find(id) end def build(attributes) if base.kind_of? Class - self.model_instance = base.new(attributes) + self.model_instance ||= base.new(attributes) else - self.model_instance = base.build(attributes) + self.model_instance ||= base.build(attributes) end end diff --git a/spec/cancan/controller_resource_spec.rb b/spec/cancan/controller_resource_spec.rb index 9c29d8c..40e77d0 100644 --- a/spec/cancan/controller_resource_spec.rb +++ b/spec/cancan/controller_resource_spec.rb @@ -34,4 +34,10 @@ describe CanCan::ControllerResource do CanCan::ControllerResource.new(@controller, :ability, parent).build(123) @controller.instance_variable_get(:@ability).should == :some_ability end + + it "should not load resource if instance variable is already provided" do + @controller.instance_variable_set(:@ability, :some_ability) + CanCan::ControllerResource.new(@controller, :ability).find(123) + @controller.instance_variable_get(:@ability).should == :some_ability + end end