using instance_exec to change scope of can blocks to instance of ability, this is a bit ugly so I may end up using methods instead

This commit is contained in:
Ryan Bates 2009-11-16 16:24:36 -08:00
parent be1892cca8
commit c663effc06
4 changed files with 32 additions and 1 deletions

View File

@ -1,2 +1,3 @@
$:.unshift(File.dirname(__FILE__)) $:.unshift(File.dirname(__FILE__))
require 'cancan/ability' require 'cancan/ability'
require 'cancan/instance_exec'

View File

@ -1,5 +1,7 @@
module CanCan module CanCan
module Ability module Ability
attr_accessor :user
def self.included(base) def self.included(base)
base.extend ClassMethods base.extend ClassMethods
base.alias_action :index, :show, :to => :read base.alias_action :index, :show, :to => :read
@ -18,7 +20,7 @@ module CanCan
block_args << action if can_action == :manage block_args << action if can_action == :manage
block_args << (target.class == Class ? target : target.class) if can_target == :all block_args << (target.class == Class ? target : target.class) if can_target == :all
block_args << (target.class == Class ? nil : target) block_args << (target.class == Class ? nil : target)
return can_block.call(*block_args) return instance_exec(*block_args, &can_block)
end end
end end
end end
@ -48,6 +50,12 @@ module CanCan
target = args.pop[:to] target = args.pop[:to]
@aliased_actions[target] = args @aliased_actions[target] = args
end end
def for_user(user)
ability = new
ability.user = user
ability
end
end end
end end
end end

View File

@ -0,0 +1,15 @@
# 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

View File

@ -77,4 +77,11 @@ describe CanCan::Ability do
@ability.can?(:new, 123).should == :create_called @ability.can?(:new, 123).should == :create_called
@ability.can?(:edit, 123).should == :update_called @ability.can?(:edit, 123).should == :update_called
end 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
end
end end