Skip to content

Commit

Permalink
Fix [#388] guard parameter for permissible states
Browse files Browse the repository at this point in the history
  • Loading branch information
anilmaurya committed Jul 31, 2016
1 parent 9866206 commit 6001f5f
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 8 deletions.
16 changes: 8 additions & 8 deletions lib/aasm/instance_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ def human_state
AASM::Localizer.new.human_state_name(@instance.class, state_object_for_name(current_state))
end

def states(options={})
def states(options={}, *args)
if options.has_key?(:permitted)
selected_events = events(:permitted => options[:permitted])
selected_events = events({:permitted => options[:permitted]}, *args)
# An array of arrays. Each inner array represents the transitions that
# transition from the current state for an event
event_transitions = selected_events.map {|e| e.transitions_from_state(current_state) }
Expand All @@ -45,10 +45,10 @@ def states(options={})
return nil if transitions.empty?

# Return the :to state of the first transition that is allowed (or not) or nil
if options[:permitted]
transition = transitions.find { |t| t.allowed?(@instance) }
if options[:permitted]
transition = transitions.find { |t| t.allowed?(@instance, *args) }
else
transition = transitions.find { |t| !t.allowed?(@instance) }
transition = transitions.find { |t| !t.allowed?(@instance, *args) }
end
transition ? transition.to : nil
end.flatten.compact.uniq
Expand All @@ -60,7 +60,7 @@ def states(options={})
end
end

def events(options={})
def events(options={}, *args)
state = options[:state] || current_state
events = @instance.class.aasm(@name).events.select {|e| e.transitions_from_state?(state) }

Expand All @@ -71,9 +71,9 @@ def events(options={})
# filters the results of events_for_current_state so that only those that
# are really currently possible (given transition guards) are shown.
if options[:permitted]
events.select! { |e| @instance.send("may_#{e.name}?") }
events.select! { |e| @instance.send("may_#{e.name}?", *args) }
else
events.select! { |e| !@instance.send("may_#{e.name}?") }
events.select! { |e| !@instance.send("may_#{e.name}?", *args) }
end
end

Expand Down
24 changes: 24 additions & 0 deletions spec/models/guard_with_params.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class GuardWithParams
include AASM
aasm do
state :new, :reviewed, :finalized

event :mark_as_reviewed do
transitions :from => :new, :to => :reviewed, :guards => [:user_is_manager?]
end
end

def user_is_manager?(user)
ok = false
if user.has_role? :manager
ok = true
end
return ok
end
end

class GuardParamsClass
def has_role?(role)
true
end
end
18 changes: 18 additions & 0 deletions spec/models/guard_with_params_multiple.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class GuardWithParamsMultiple
include AASM
aasm(:left) do
state :new, :reviewed, :finalized

event :mark_as_reviewed do
transitions :from => :new, :to => :reviewed, :guards => [:user_is_manager?]
end
end

def user_is_manager?(user)
ok = false
if user.has_role? :manager
ok = true
end
return ok
end
end
10 changes: 10 additions & 0 deletions spec/unit/guard_with_params_multiple_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require 'spec_helper'

describe "guards with params" do
let(:guard) { GuardWithParamsMultiple.new }
let(:user) {GuardParamsClass.new}

it "list permitted states" do
expect(guard.aasm(:left).states({:permitted => true}, user).map(&:name)).to eql [:reviewed]
end
end
10 changes: 10 additions & 0 deletions spec/unit/guard_with_params_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require 'spec_helper'

describe "guards with params" do
let(:guard) { GuardWithParams.new }
let(:user) {GuardParamsClass.new}

it "list permitted states" do
expect(guard.aasm.states({:permitted => true}, user).map(&:name)).to eql [:reviewed]
end
end

0 comments on commit 6001f5f

Please sign in to comment.