moving can definition into ability instance instead of class, this removes ugly instance_exec command
This commit is contained in:
		
							parent
							
								
									7b299b50fc
								
							
						
					
					
						commit
						4b6f538663
					
				@ -2,6 +2,5 @@ module CanCan
 | 
			
		||||
  class AccessDenied < StandardError; end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
require File.dirname(__FILE__) + '/cancan/instance_exec'
 | 
			
		||||
require File.dirname(__FILE__) + '/cancan/ability'
 | 
			
		||||
require File.dirname(__FILE__) + '/cancan/controller_additions'
 | 
			
		||||
 | 
			
		||||
@ -2,15 +2,8 @@ module CanCan
 | 
			
		||||
  module Ability
 | 
			
		||||
    attr_accessor :user
 | 
			
		||||
    
 | 
			
		||||
    def self.included(base)
 | 
			
		||||
      base.extend ClassMethods
 | 
			
		||||
      base.alias_action :index, :show, :to => :read
 | 
			
		||||
      base.alias_action :new, :to => :create
 | 
			
		||||
      base.alias_action :edit, :to => :update
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    def can?(original_action, target) # TODO this could use some refactoring
 | 
			
		||||
      (self.class.can_history || []).reverse.each do |can_action, can_target, can_block|
 | 
			
		||||
      (@can_history || []).reverse.each do |can_action, can_target, can_block|
 | 
			
		||||
        possible_actions_for(original_action).each do |action|
 | 
			
		||||
          if (can_action == :manage || can_action == action) && (can_target == :all || can_target == target || target.kind_of?(can_target))
 | 
			
		||||
            if can_block.nil?
 | 
			
		||||
@ -20,7 +13,7 @@ module CanCan
 | 
			
		||||
              block_args << action if can_action == :manage
 | 
			
		||||
              block_args << (target.class == Class ? target : target.class) if can_target == :all
 | 
			
		||||
              block_args << (target.class == Class ? nil : target)
 | 
			
		||||
              return instance_exec(*block_args, &can_block)
 | 
			
		||||
              return can_block.call(*block_args)
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
@ -30,32 +23,33 @@ module CanCan
 | 
			
		||||
    
 | 
			
		||||
    def possible_actions_for(initial_action)
 | 
			
		||||
      actions = [initial_action]
 | 
			
		||||
      (self.class.aliased_actions || []).each do |target, aliases|
 | 
			
		||||
      (@aliased_actions || default_alias_actions).each do |target, aliases|
 | 
			
		||||
        actions += possible_actions_for(target) if aliases.include? initial_action
 | 
			
		||||
      end
 | 
			
		||||
      actions
 | 
			
		||||
    end
 | 
			
		||||
      
 | 
			
		||||
    module ClassMethods
 | 
			
		||||
      attr_reader :can_history
 | 
			
		||||
      attr_reader :aliased_actions
 | 
			
		||||
    def can(action, target, &block)
 | 
			
		||||
      @can_history ||= []
 | 
			
		||||
      @can_history << [action, target, block]
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
      def can(action, target, &block)
 | 
			
		||||
        @can_history ||= []
 | 
			
		||||
        @can_history << [action, target, block]
 | 
			
		||||
      end
 | 
			
		||||
    def alias_action(*args)
 | 
			
		||||
      @aliased_actions ||= default_alias_actions
 | 
			
		||||
      target = args.pop[:to]
 | 
			
		||||
      @aliased_actions[target] = args
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
      def alias_action(*args)
 | 
			
		||||
        @aliased_actions ||= {}
 | 
			
		||||
        target = args.pop[:to]
 | 
			
		||||
        @aliased_actions[target] = args
 | 
			
		||||
      end
 | 
			
		||||
    def default_alias_actions
 | 
			
		||||
      {
 | 
			
		||||
        :read => [:index, :show],
 | 
			
		||||
        :create => [:new],
 | 
			
		||||
        :update => [:edit],
 | 
			
		||||
      }
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
      def for_user(user)
 | 
			
		||||
        ability = new
 | 
			
		||||
        ability.user = user
 | 
			
		||||
        ability
 | 
			
		||||
      end
 | 
			
		||||
    def prepare(user)
 | 
			
		||||
      # to be overriden by included class
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,9 @@ module CanCan
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    def current_ability
 | 
			
		||||
      ::Ability.for_user(current_user)
 | 
			
		||||
      ability = ::Ability.new
 | 
			
		||||
      ability.prepare(current_user)
 | 
			
		||||
      ability
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    def can?(*args)
 | 
			
		||||
 | 
			
		||||
@ -1,15 +0,0 @@
 | 
			
		||||
# see http://eigenclass.org/hiki.rb?instance_exec
 | 
			
		||||
class Object
 | 
			
		||||
  module InstanceExecHelper; end
 | 
			
		||||
  include InstanceExecHelper
 | 
			
		||||
  def instance_exec(*args, &block) # !> method redefined; discarding old instance_exec
 | 
			
		||||
    mname = "__instance_exec_#{Thread.current.object_id.abs}_#{object_id.abs}"
 | 
			
		||||
    InstanceExecHelper.module_eval{ define_method(mname, &block) }
 | 
			
		||||
    begin
 | 
			
		||||
      ret = send(mname, *args)
 | 
			
		||||
    ensure
 | 
			
		||||
      InstanceExecHelper.module_eval{ undef_method(mname) } rescue nil
 | 
			
		||||
    end
 | 
			
		||||
    ret
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -8,7 +8,7 @@ describe CanCan::Ability do
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  it "should be able to :read anything" do
 | 
			
		||||
    @ability_class.can :read, :all
 | 
			
		||||
    @ability.can :read, :all
 | 
			
		||||
    @ability.can?(:read, String).should be_true
 | 
			
		||||
    @ability.can?(:read, 123).should be_true
 | 
			
		||||
  end
 | 
			
		||||
@ -18,8 +18,8 @@ describe CanCan::Ability do
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  it "should return what block returns on a can call" do
 | 
			
		||||
    @ability_class.can :read, :all
 | 
			
		||||
    @ability_class.can :read, Symbol do |sym|
 | 
			
		||||
    @ability.can :read, :all
 | 
			
		||||
    @ability.can :read, Symbol do |sym|
 | 
			
		||||
      sym
 | 
			
		||||
    end
 | 
			
		||||
    @ability.can?(:read, Symbol).should be_nil
 | 
			
		||||
@ -27,21 +27,21 @@ describe CanCan::Ability do
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  it "should pass class with object if :all objects are accepted" do
 | 
			
		||||
    @ability_class.can :preview, :all do |object_class, object|
 | 
			
		||||
    @ability.can :preview, :all do |object_class, object|
 | 
			
		||||
      [object_class, object]
 | 
			
		||||
    end
 | 
			
		||||
    @ability.can?(:preview, 123).should == [Fixnum, 123]
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  it "should pass class with no object if :all objects are accepted and class is passed directly" do
 | 
			
		||||
    @ability_class.can :preview, :all do |object_class, object|
 | 
			
		||||
    @ability.can :preview, :all do |object_class, object|
 | 
			
		||||
      [object_class, object]
 | 
			
		||||
    end
 | 
			
		||||
    @ability.can?(:preview, Hash).should == [Hash, nil]
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  it "should pass action and object for global manage actions" do
 | 
			
		||||
    @ability_class.can :manage, Array do |action, object|
 | 
			
		||||
    @ability.can :manage, Array do |action, object|
 | 
			
		||||
      [action, object]
 | 
			
		||||
    end
 | 
			
		||||
    @ability.can?(:stuff, [1, 2]).should == [:stuff, [1, 2]]
 | 
			
		||||
@ -49,8 +49,8 @@ describe CanCan::Ability do
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  it "should alias update or destroy actions to modify action" do
 | 
			
		||||
    @ability_class.alias_action :update, :destroy, :to => :modify
 | 
			
		||||
    @ability_class.can :modify, :all do |object_class, object|
 | 
			
		||||
    @ability.alias_action :update, :destroy, :to => :modify
 | 
			
		||||
    @ability.can :modify, :all do |object_class, object|
 | 
			
		||||
      :modify_called
 | 
			
		||||
    end
 | 
			
		||||
    @ability.can?(:update, 123).should == :modify_called
 | 
			
		||||
@ -58,7 +58,7 @@ describe CanCan::Ability do
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  it "should return block result for action, object_class, and object for any action" do
 | 
			
		||||
    @ability_class.can :manage, :all do |action, object_class, object|
 | 
			
		||||
    @ability.can :manage, :all do |action, object_class, object|
 | 
			
		||||
      [action, object_class, object]
 | 
			
		||||
    end
 | 
			
		||||
    @ability.can?(:foo, 123).should == [:foo, Fixnum, 123]
 | 
			
		||||
@ -66,22 +66,19 @@ describe CanCan::Ability do
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  it "should automatically alias index and show into read calls" do
 | 
			
		||||
    @ability_class.can :read, :all
 | 
			
		||||
    @ability.can :read, :all
 | 
			
		||||
    @ability.can?(:index, 123).should be_true
 | 
			
		||||
    @ability.can?(:show, 123).should be_true
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  it "should automatically alias new and edit into create and update respectively" do
 | 
			
		||||
    @ability_class.can(:create, :all) { :create_called }
 | 
			
		||||
    @ability_class.can(:update, :all) { :update_called }
 | 
			
		||||
    @ability.can(:create, :all) { :create_called }
 | 
			
		||||
    @ability.can(:update, :all) { :update_called }
 | 
			
		||||
    @ability.can?(:new, 123).should == :create_called
 | 
			
		||||
    @ability.can?(:edit, 123).should == :update_called
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  it "should be able to access given user" do
 | 
			
		||||
    @ability_class.can(:preview, :all) { user }
 | 
			
		||||
    ability = @ability_class.for_user(:some_user)
 | 
			
		||||
    ability.user.should == :some_user
 | 
			
		||||
    ability.can?(:preview, 123).should == :some_user
 | 
			
		||||
  it "should respond to prepare" do
 | 
			
		||||
    @ability.should respond_to(:prepare)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,6 @@ describe CanCan::ControllerAdditions do
 | 
			
		||||
  it "should have a current_ability method which generates an ability for the current user" do
 | 
			
		||||
    stub(@controller).current_user { :current_user }
 | 
			
		||||
    @controller.current_ability.should be_kind_of(Ability)
 | 
			
		||||
    @controller.current_ability.user.should == :current_user
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  it "should provide a can? method which goes through the current ability" do
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user