supporting deeply nested aliases - closes #98

This commit is contained in:
Ryan Bates 2010-07-19 16:03:09 -07:00
parent 1b4377cbf3
commit cad425989e
5 changed files with 22 additions and 10 deletions

View File

@ -1,3 +1,5 @@
* Supporting deeply nested aliases - see issue #98
1.2.0 (July 16, 2010) 1.2.0 (July 16, 2010)
* Load nested parent resources on collection actions such as "index" (thanks dohzya) * Load nested parent resources on collection actions such as "index" (thanks dohzya)

View File

@ -213,13 +213,22 @@ module CanCan
private private
# Accepts a hash of aliased actions and returns an array of actions which match.
# This should be called before "matches?" and other checking methods since they
# rely on the actions to be expanded.
def expand_actions(actions)
actions.map do |action|
aliased_actions[action] ? [action, *expand_actions(aliased_actions[action])] : action
end.flatten
end
def can_definitions def can_definitions
@can_definitions ||= [] @can_definitions ||= []
end end
def matching_can_definition(action, subject) def matching_can_definition(action, subject)
can_definitions.reverse.detect do |can_definition| can_definitions.reverse.detect do |can_definition|
can_definition.expand_actions(aliased_actions) can_definition.expanded_actions = expand_actions(can_definition.actions)
can_definition.matches? action, subject can_definition.matches? action, subject
end end
end end

View File

@ -5,6 +5,8 @@ module CanCan
class CanDefinition # :nodoc: class CanDefinition # :nodoc:
include ActiveSupport::Inflector include ActiveSupport::Inflector
attr_reader :block attr_reader :block
attr_reader :actions
attr_writer :expanded_actions
# The first argument when initializing is the base_behavior which is a true/false # The first argument when initializing is the base_behavior which is a true/false
# value. True for "can" and false for "cannot". The next two arguments are the action # value. True for "can" and false for "cannot". The next two arguments are the action
@ -18,15 +20,6 @@ module CanCan
@block = block @block = block
end end
# Accepts a hash of aliased actions and returns an array of actions which match.
# This should be called before "matches?" and other checking methods since they
# rely on the actions to be expanded.
def expand_actions(aliased_actions)
@expanded_actions = @actions.map do |action|
aliased_actions[action] ? [action, *aliased_actions[action]] : action
end.flatten
end
def matches?(action, subject) def matches?(action, subject)
matches_action?(action) && matches_subject?(subject) matches_action?(action) && matches_subject?(subject)
end end

View File

@ -54,6 +54,13 @@ describe CanCan::Ability do
@ability.can?(:destroy, 123).should == :modify_called @ability.can?(:destroy, 123).should == :modify_called
end end
it "should allow deeply nested aliased actions" do
@ability.alias_action :increment, :to => :sort
@ability.alias_action :sort, :to => :modify
@ability.can :modify, :all
@ability.can?(:increment, 123).should be_true
end
it "should return block result for action, object_class, and object for any action" do it "should return block result for action, object_class, and object for any action" do
@ability.can :manage, :all do |action, object_class, object| @ability.can :manage, :all do |action, object_class, object|
[action, object_class, object] [action, object_class, object]

1
spec/spec.opts Normal file
View File

@ -0,0 +1 @@
--color