mirror of
https://github.com/aasm/aasm
synced 2023-03-27 23:22:41 -04:00
fire guards only once per transition #184
This commit is contained in:
parent
8ce7062aa8
commit
aac1ece778
6 changed files with 20 additions and 18 deletions
|
@ -4,6 +4,10 @@
|
|||
|
||||
* `aasm_human_event_name` is deprecated, use `aasm.human_event_name` instead
|
||||
|
||||
## 4.0.1
|
||||
|
||||
* fire guards only once per transition (see [issue #184](https://github.com/aasm/aasm/issues/184) for details)
|
||||
|
||||
## 4.0.0
|
||||
|
||||
* support `if` and `unless` guard syntax: (see [issue #179](https://github.com/aasm/aasm/issues/179) and [issue #181](https://github.com/aasm/aasm/issues/181)), thanks to [@bigtunacan](https://github.com/bigtunacan)
|
||||
|
|
|
@ -141,14 +141,12 @@ Here you can see a list of all possible callbacks, together with their order of
|
|||
```ruby
|
||||
begin
|
||||
event before
|
||||
event guards # test run
|
||||
transition guards # test run
|
||||
event guards
|
||||
transition guards
|
||||
old_state before_exit
|
||||
old_state exit
|
||||
new_state before_enter
|
||||
new_state enter
|
||||
event guards
|
||||
transition guards
|
||||
...update state...
|
||||
transition after
|
||||
event success # if persist successful
|
||||
|
|
|
@ -86,11 +86,11 @@ private
|
|||
*process_args(event, aasm.current_state, *args)
|
||||
)
|
||||
|
||||
if event.may_fire?(self, *args)
|
||||
if may_fire_to = event.may_fire?(self, *args)
|
||||
old_state.fire_callbacks(:before_exit, self)
|
||||
old_state.fire_callbacks(:exit, self) # TODO: remove for AASM 4?
|
||||
|
||||
if new_state_name = event.fire(self, *args)
|
||||
if new_state_name = event.fire(self, {:may_fire => may_fire_to}, *args)
|
||||
aasm_fired(event, old_state, new_state_name, options, *args, &block)
|
||||
else
|
||||
aasm_failed(event_name, old_state)
|
||||
|
|
|
@ -19,11 +19,11 @@ module AASM
|
|||
# executes the transition guards to determine if a transition is even
|
||||
# an option given current conditions.
|
||||
def may_fire?(obj, to_state=nil, *args)
|
||||
_fire(obj, true, to_state, *args) # true indicates test firing
|
||||
_fire(obj, {:test_only => true}, to_state, *args) # true indicates test firing
|
||||
end
|
||||
|
||||
def fire(obj, to_state=nil, *args)
|
||||
_fire(obj, false, to_state, *args) # false indicates this is not a test (fire!)
|
||||
def fire(obj, options={}, to_state=nil, *args)
|
||||
_fire(obj, options, to_state, *args) # false indicates this is not a test (fire!)
|
||||
end
|
||||
|
||||
def transitions_from_state?(state)
|
||||
|
@ -86,8 +86,8 @@ module AASM
|
|||
end
|
||||
|
||||
# Execute if test == false, otherwise return true/false depending on whether it would fire
|
||||
def _fire(obj, test, to_state=nil, *args)
|
||||
result = test ? false : nil
|
||||
def _fire(obj, options={}, to_state=nil, *args)
|
||||
result = options[:test_only] ? false : nil
|
||||
if @transitions.map(&:from).any?
|
||||
transitions = @transitions.select { |t| t.from == obj.aasm.current_state }
|
||||
return result if transitions.size == 0
|
||||
|
@ -106,11 +106,11 @@ module AASM
|
|||
|
||||
transitions.each do |transition|
|
||||
next if to_state and !Array(transition.to).include?(to_state)
|
||||
if transition.allowed?(obj, *args)
|
||||
if test
|
||||
result = true
|
||||
if Array(transition.to).include?(options[:may_fire]) || transition.allowed?(obj, *args)
|
||||
result = to_state || Array(transition.to).first
|
||||
if options[:test_only]
|
||||
# result = true
|
||||
else
|
||||
result = to_state || Array(transition.to).first
|
||||
transition.execute(obj, *args)
|
||||
end
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ describe 'callbacks for the new DSL' do
|
|||
expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
|
||||
expect(callback).to receive(:before_exit_open).once.ordered # these should be before the state changes
|
||||
expect(callback).to receive(:exit_open).once.ordered
|
||||
expect(callback).to receive(:event_guard).once.ordered.and_return(true)
|
||||
expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
|
||||
# expect(callback).to receive(:event_guard).once.ordered.and_return(true)
|
||||
# expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
|
||||
expect(callback).to receive(:transitioning).once.ordered
|
||||
expect(callback).to receive(:before_enter_closed).once.ordered
|
||||
expect(callback).to receive(:enter_closed).once.ordered
|
||||
|
|
|
@ -101,7 +101,7 @@ describe 'firing an event' do
|
|||
obj = double('object', :aasm => double('aasm', :current_state => :open))
|
||||
expect(obj).to receive(:guard_fn).with('arg1', 'arg2').and_return(true)
|
||||
|
||||
expect(event.fire(obj, nil, 'arg1', 'arg2')).to eq(:closed)
|
||||
expect(event.fire(obj, {}, nil, 'arg1', 'arg2')).to eq(:closed)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue