diff --git a/README.md b/README.md index 5d8c295..11beb23 100644 --- a/README.md +++ b/README.md @@ -1141,6 +1141,10 @@ job = Job.new job.aasm.states(permitted: true).map(&:name) #=> [:running] +# List all the permitted transitions(event and state pairs) from initial state +job.aasm.permitted_transitions +#=> [{ :event => :run, :state => :running }] + job.run job.aasm.states(permitted: true).map(&:name) #=> [:sleeping] diff --git a/lib/aasm/instance_base.rb b/lib/aasm/instance_base.rb index cca8dd2..b609618 100644 --- a/lib/aasm/instance_base.rb +++ b/lib/aasm/instance_base.rb @@ -78,6 +78,17 @@ module AASM events end + def permitted_transitions + events(permitted: true).flat_map do |event| + available_transitions = event.transitions_from_state(current_state) + allowed_transitions = available_transitions.select { |t| t.allowed?(@instance) } + + allowed_transitions.map do |transition| + { event: event.name, state: transition.to } + end + end + end + def state_object_for_name(name) obj = @instance.class.aasm(@name).states.find {|s| s.name == name} raise AASM::UndefinedState, "State :#{name} doesn't exist" if obj.nil? diff --git a/spec/models/simple_example.rb b/spec/models/simple_example.rb index e9afabf..1275d8d 100644 --- a/spec/models/simple_example.rb +++ b/spec/models/simple_example.rb @@ -3,11 +3,17 @@ class SimpleExample aasm do state :initialised, :initial => true state :filled_out + state :denied state :authorised event :fill_out do transitions :from => :initialised, :to => :filled_out end + + event :deny do + transitions from: :initialised, to: :denied + end + event :authorise do transitions :from => :filled_out, :to => :authorised end diff --git a/spec/unit/simple_example_spec.rb b/spec/unit/simple_example_spec.rb index 85fea04..0d1a9ec 100644 --- a/spec/unit/simple_example_spec.rb +++ b/spec/unit/simple_example_spec.rb @@ -23,6 +23,21 @@ describe 'state machine' do expect(simple).to be_authorised end + it 'shows the permitted transitions' do + expect(simple.aasm.permitted_transitions).to eq( + [ + { event: :fill_out, state: :filled_out }, + { event: :deny, state: :denied } + ] + ) + + simple.fill_out! + expect(simple.aasm.permitted_transitions).to eq([{ event: :authorise, state: :authorised }]) + + simple.authorise + expect(simple.aasm.permitted_transitions).to eq([]) + end + it 'denies transitions to other states' do expect {simple.authorise}.to raise_error(AASM::InvalidTransition) expect {simple.authorise!}.to raise_error(AASM::InvalidTransition)