support reading from- and to-state during on_transition callback #100

This commit is contained in:
Thorsten Böttger 2014-01-27 21:51:38 +01:00
parent 5f8be13c8c
commit ca88fefd01
5 changed files with 36 additions and 6 deletions

View File

@ -10,6 +10,7 @@
* allow configuring behavior of nested transactions (see [issue #107](https://github.com/aasm/aasm/issues/107))
* support multiple guards per transition
* support event guards (see [issue #85](https://github.com/aasm/aasm/issues/85))
* support reading from- and to-state during on_transition callback (see [issue #100](https://github.com/aasm/aasm/issues/100))
## 3.0.26

View File

@ -152,6 +152,15 @@ In this case the `set_process` would be called with `:defagmentation` argument.
In case of an error during the event processing the error is rescued and passed to `:error`
callback, which can handle it or re-raise it for further propagation.
During the `:on_transition` callback (and reliably only then) you can access the
originating state (the from-state) and the target state (the to state), like this:
```ruby
def set_process(name)
logger.info "from #{aasm.from_state} to #{aasm.to_state}"
end
```
### Guards
Let's assume you want to allow particular transitions only if a defined condition is

View File

@ -1,6 +1,8 @@
module AASM
class InstanceBase
attr_accessor :from_state, :to_state
def initialize(instance)
@instance = instance
end

View File

@ -41,6 +41,9 @@ module AASM
private
def _execute(obj, on_transition, *args)
obj.aasm.from_state = @from if obj.aasm.respond_to?(:from_state=)
obj.aasm.to_state = @to if obj.aasm.respond_to?(:to_state=)
case on_transition
when Proc
on_transition.arity == 0 ? on_transition.call : on_transition.call(obj, *args)

View File

@ -139,7 +139,7 @@ describe AASM::Transition, '- when executing the transition with a Proc' do
opts = {:from => 'foo', :to => 'bar', :on_transition => Proc.new {|o| o.test}}
st = AASM::Transition.new(opts)
args = {:arg1 => '1', :arg2 => '2'}
obj = double('object')
obj = double('object', :aasm => 'aasm')
expect(opts[:on_transition]).to receive(:call).with(any_args)
@ -150,7 +150,7 @@ describe AASM::Transition, '- when executing the transition with a Proc' do
opts = {:from => 'foo', :to => 'bar', :on_transition => Proc.new {||}}
st = AASM::Transition.new(opts)
args = {:arg1 => '1', :arg2 => '2'}
obj = double('object')
obj = double('object', :aasm => 'aasm')
expect(opts[:on_transition]).to receive(:call).with(no_args)
@ -163,7 +163,7 @@ describe AASM::Transition, '- when executing the transition with an :on_transtio
opts = {:from => 'foo', :to => 'bar', :on_transition => 'test'}
st = AASM::Transition.new(opts)
args = {:arg1 => '1', :arg2 => '2'}
obj = double('object')
obj = double('object', :aasm => 'aasm')
expect(obj).to receive(:test)
@ -174,7 +174,7 @@ describe AASM::Transition, '- when executing the transition with an :on_transtio
opts = {:from => 'foo', :to => 'bar', :on_transition => :test}
st = AASM::Transition.new(opts)
args = {:arg1 => '1', :arg2 => '2'}
obj = double('object')
obj = double('object', :aasm => 'aasm')
expect(obj).to receive(:test)
@ -185,7 +185,7 @@ describe AASM::Transition, '- when executing the transition with an :on_transtio
opts = {:from => 'foo', :to => 'bar', :on_transition => :test}
st = AASM::Transition.new(opts)
args = {:arg1 => '1', :arg2 => '2'}
obj = double('object')
obj = double('object', :aasm => 'aasm')
def obj.test(args)
"arg1: #{args[:arg1]} arg2: #{args[:arg2]}"
@ -200,7 +200,7 @@ describe AASM::Transition, '- when executing the transition with an :on_transtio
opts = {:from => 'foo', :to => 'bar', :on_transition => :test}
st = AASM::Transition.new(opts)
args = {:arg1 => '1', :arg2 => '2'}
obj = double('object')
obj = double('object', :aasm => 'aasm')
def obj.test
'success'
@ -211,4 +211,19 @@ describe AASM::Transition, '- when executing the transition with an :on_transtio
expect(return_value).to eq('success')
end
it 'should allow accessing the from_state and the to_state' do
opts = {:from => 'foo', :to => 'bar', :on_transition => :test}
st = AASM::Transition.new(opts)
args = {:arg1 => '1', :arg2 => '2'}
obj = double('object', :aasm => AASM::InstanceBase.new('object'))
def obj.test(args)
"from: #{aasm.from_state} to: #{aasm.to_state}"
end
return_value = st.execute(obj, args)
expect(return_value).to eq('from: foo to: bar')
end
end