adding support for loading through Inherited Resources - closes #23
This commit is contained in:
parent
a5ff826e40
commit
4eee637270
|
@ -5,3 +5,4 @@ require 'cancan/controller_additions'
|
||||||
require 'cancan/active_record_additions'
|
require 'cancan/active_record_additions'
|
||||||
require 'cancan/exceptions'
|
require 'cancan/exceptions'
|
||||||
require 'cancan/query'
|
require 'cancan/query'
|
||||||
|
require 'cancan/inherited_resource'
|
||||||
|
|
|
@ -12,7 +12,7 @@ module CanCan
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
def load_and_authorize_resource(*args)
|
def load_and_authorize_resource(*args)
|
||||||
ControllerResource.add_before_filter(self, :load_and_authorize_resource, *args)
|
cancan_resource_class.add_before_filter(self, :load_and_authorize_resource, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets up a before filter which loads the model resource into an instance variable.
|
# Sets up a before filter which loads the model resource into an instance variable.
|
||||||
|
@ -103,7 +103,7 @@ module CanCan
|
||||||
# load_resource :new => :build
|
# load_resource :new => :build
|
||||||
#
|
#
|
||||||
def load_resource(*args)
|
def load_resource(*args)
|
||||||
ControllerResource.add_before_filter(self, :load_resource, *args)
|
cancan_resource_class.add_before_filter(self, :load_resource, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets up a before filter which authorizes the resource using the instance variable.
|
# Sets up a before filter which authorizes the resource using the instance variable.
|
||||||
|
@ -156,7 +156,7 @@ module CanCan
|
||||||
# Authorize conditions on this parent resource when instance isn't available.
|
# Authorize conditions on this parent resource when instance isn't available.
|
||||||
#
|
#
|
||||||
def authorize_resource(*args)
|
def authorize_resource(*args)
|
||||||
ControllerResource.add_before_filter(self, :authorize_resource, *args)
|
cancan_resource_class.add_before_filter(self, :authorize_resource, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add this to a controller to ensure it performs authorization through +authorized+! or +authorize_resource+ call.
|
# Add this to a controller to ensure it performs authorization through +authorized+! or +authorize_resource+ call.
|
||||||
|
@ -190,6 +190,14 @@ module CanCan
|
||||||
controller.instance_variable_set(:@_authorized, true)
|
controller.instance_variable_set(:@_authorized, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cancan_resource_class
|
||||||
|
if ancestors.map(&:to_s).include? "InheritedResources::Actions"
|
||||||
|
InheritedResource
|
||||||
|
else
|
||||||
|
ControllerResource
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.included(base)
|
def self.included(base)
|
||||||
|
|
|
@ -26,10 +26,10 @@ module CanCan
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_resource
|
def load_resource
|
||||||
if !resource_instance && (parent? || member_action?)
|
if parent? || member_action?
|
||||||
@controller.instance_variable_set("@#{instance_name}", load_resource_instance)
|
self.resource_instance ||= load_resource_instance
|
||||||
elsif load_collection?
|
elsif load_collection?
|
||||||
@controller.instance_variable_set("@#{instance_name.to_s.pluralize}", load_collection)
|
self.collection_instance ||= load_collection
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ module CanCan
|
||||||
@options.has_key?(:parent) ? @options[:parent] : @name && @name != name_from_controller.to_sym
|
@options.has_key?(:parent) ? @options[:parent] : @name && @name != name_from_controller.to_sym
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
protected
|
||||||
|
|
||||||
def load_resource_instance
|
def load_resource_instance
|
||||||
if !parent? && new_actions.include?(@params[:action].to_sym)
|
if !parent? && new_actions.include?(@params[:action].to_sym)
|
||||||
|
@ -52,7 +52,6 @@ module CanCan
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_collection?
|
def load_collection?
|
||||||
!parent? && collection_actions.include?(@params[:action].to_sym) &&
|
|
||||||
resource_base.respond_to?(:accessible_by) &&
|
resource_base.respond_to?(:accessible_by) &&
|
||||||
!@controller.current_ability.has_block?(authorization_action, resource_class)
|
!@controller.current_ability.has_block?(authorization_action, resource_class)
|
||||||
end
|
end
|
||||||
|
@ -110,10 +109,22 @@ module CanCan
|
||||||
parent_resource ? {parent_resource => resource_class} : resource_class
|
parent_resource ? {parent_resource => resource_class} : resource_class
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def resource_instance=(instance)
|
||||||
|
@controller.instance_variable_set("@#{instance_name}", instance)
|
||||||
|
end
|
||||||
|
|
||||||
def resource_instance
|
def resource_instance
|
||||||
@controller.instance_variable_get("@#{instance_name}")
|
@controller.instance_variable_get("@#{instance_name}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def collection_instance=(instance)
|
||||||
|
@controller.instance_variable_set("@#{instance_name.to_s.pluralize}", instance)
|
||||||
|
end
|
||||||
|
|
||||||
|
def collection_instance
|
||||||
|
@controller.instance_variable_get("@#{instance_name.to_s.pluralize}")
|
||||||
|
end
|
||||||
|
|
||||||
# The object that methods (such as "find", "new" or "build") are called on.
|
# The object that methods (such as "find", "new" or "build") are called on.
|
||||||
# If the :through option is passed it will go through an association on that instance.
|
# If the :through option is passed it will go through an association on that instance.
|
||||||
# If the :singleton option is passed it won't use the association because it needs to be handled later.
|
# If the :singleton option is passed it won't use the association because it needs to be handled later.
|
||||||
|
|
18
lib/cancan/inherited_resource.rb
Normal file
18
lib/cancan/inherited_resource.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
module CanCan
|
||||||
|
# For use with Inherited Resources
|
||||||
|
class InheritedResource < ControllerResource # :nodoc:
|
||||||
|
def load_resource_instance
|
||||||
|
if parent?
|
||||||
|
@controller.parent
|
||||||
|
elsif new_actions.include? @params[:action].to_sym
|
||||||
|
@controller.build_resource
|
||||||
|
else
|
||||||
|
@controller.resource
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def resource_base
|
||||||
|
@controller.end_of_association_chain
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -74,4 +74,13 @@ describe CanCan::ControllerAdditions do
|
||||||
@controller_class.check_authorization(:some_options)
|
@controller_class.check_authorization(:some_options)
|
||||||
}.should_not raise_error(CanCan::AuthorizationNotPerformed)
|
}.should_not raise_error(CanCan::AuthorizationNotPerformed)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "cancan_resource_class should be ControllerResource by default" do
|
||||||
|
@controller.class.cancan_resource_class.should == CanCan::ControllerResource
|
||||||
|
end
|
||||||
|
|
||||||
|
it "cancan_resource_class should be InheritedResource when class includes InheritedResources::Actions" do
|
||||||
|
stub(@controller.class).ancestors { ["InheritedResources::Actions"] }
|
||||||
|
@controller.class.cancan_resource_class.should == CanCan::InheritedResource
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
40
spec/cancan/inherited_resource_spec.rb
Normal file
40
spec/cancan/inherited_resource_spec.rb
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
require "spec_helper"
|
||||||
|
|
||||||
|
describe CanCan::InheritedResource do
|
||||||
|
before(:each) do
|
||||||
|
@params = HashWithIndifferentAccess.new(:controller => "projects")
|
||||||
|
@controller = Object.new # simple stub for now
|
||||||
|
@ability = Ability.new(nil)
|
||||||
|
stub(@controller).params { @params }
|
||||||
|
stub(@controller).current_ability { @ability }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "show should load resource through @controller.resource" do
|
||||||
|
@params[:action] = "show"
|
||||||
|
stub(@controller).resource { :project_resource }
|
||||||
|
CanCan::InheritedResource.new(@controller).load_resource
|
||||||
|
@controller.instance_variable_get(:@project).should == :project_resource
|
||||||
|
end
|
||||||
|
|
||||||
|
it "new should load through @controller.build_resource" do
|
||||||
|
@params[:action] = "new"
|
||||||
|
stub(@controller).build_resource { :project_resource }
|
||||||
|
CanCan::InheritedResource.new(@controller).load_resource
|
||||||
|
@controller.instance_variable_get(:@project).should == :project_resource
|
||||||
|
end
|
||||||
|
|
||||||
|
it "index should load through @controller.parent when parent" do
|
||||||
|
@params[:action] = "index"
|
||||||
|
stub(@controller).parent { :project_resource }
|
||||||
|
CanCan::InheritedResource.new(@controller, :parent => true).load_resource
|
||||||
|
@controller.instance_variable_get(:@project).should == :project_resource
|
||||||
|
end
|
||||||
|
|
||||||
|
it "index should load through @controller.end_of_association_chain" do
|
||||||
|
@params[:action] = "index"
|
||||||
|
stub(Project).accessible_by(@ability) { :projects }
|
||||||
|
stub(@controller).end_of_association_chain { Project }
|
||||||
|
CanCan::InheritedResource.new(@controller).load_resource
|
||||||
|
@controller.instance_variable_get(:@projects).should == :projects
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user