mirror of
https://github.com/aasm/aasm
synced 2023-03-27 23:22:41 -04:00
support multiple guards per transition
This commit is contained in:
parent
cc19ab60fd
commit
39f85dbfdf
5 changed files with 85 additions and 6 deletions
|
@ -6,6 +6,7 @@
|
|||
|
||||
## 3.1.0 (not yet released)
|
||||
|
||||
* support multiple guards per transition
|
||||
* allow configuring behavior of nested transactions (see [issue #107](https://github.com/aasm/aasm/issues/107))
|
||||
* validating the current state (see [issue #95](https://github.com/aasm/aasm/issues/95), thanks to [@ivantsepp](https://github.com/ivantsepp))
|
||||
|
||||
|
|
|
@ -193,6 +193,13 @@ job.may_sleep? # => false
|
|||
job.sleep # => raises AASM::InvalidTransition
|
||||
```
|
||||
|
||||
You can even provide a number of guards, which all have to succeed to proceed
|
||||
|
||||
```ruby
|
||||
event :sleep do
|
||||
transitions :from => :running, :to => :sleeping, :guards => [:cleaning_needed?, :walked_the_dog?]
|
||||
end
|
||||
```
|
||||
|
||||
### ActiveRecord
|
||||
|
||||
|
|
|
@ -4,20 +4,24 @@ module AASM
|
|||
alias_method :options, :opts
|
||||
|
||||
def initialize(opts)
|
||||
@from, @to, @guard, @on_transition = opts[:from], opts[:to], opts[:guard], opts[:on_transition]
|
||||
@from = opts[:from]
|
||||
@to = opts[:to]
|
||||
@guards = Array(opts[:guard] || opts[:guards])
|
||||
@on_transition = opts[:on_transition]
|
||||
@opts = opts
|
||||
end
|
||||
|
||||
# TODO: should be named allowed? or similar
|
||||
def perform(obj, *args)
|
||||
case @guard
|
||||
@guards.each do |guard|
|
||||
case guard
|
||||
when Symbol, String
|
||||
obj.send(@guard, *args)
|
||||
return false unless obj.send(guard, *args)
|
||||
when Proc
|
||||
@guard.call(obj, *args)
|
||||
else
|
||||
true
|
||||
return false unless guard.call(obj, *args)
|
||||
end
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def execute(obj, *args)
|
||||
|
|
37
spec/models/guardian.rb
Normal file
37
spec/models/guardian.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
class Guardian
|
||||
include AASM
|
||||
|
||||
aasm do
|
||||
state :alpha, :initial => true
|
||||
state :beta
|
||||
|
||||
event :use_one_guard_that_succeeds do
|
||||
transitions :from => :alpha, :to => :beta, :guard => :succeed
|
||||
end
|
||||
event :use_one_guard_that_fails do
|
||||
transitions :from => :alpha, :to => :beta, :guard => :fail
|
||||
end
|
||||
event :use_guards_that_succeed do
|
||||
transitions :from => :alpha, :to => :beta, :guards => [:succeed, :another_succeed]
|
||||
end
|
||||
event :use_guards_where_the_first_fails do
|
||||
transitions :from => :alpha, :to => :beta, :guards => [:succeed, :fail]
|
||||
end
|
||||
event :use_guards_where_the_second_fails do
|
||||
transitions :from => :alpha, :to => :beta, :guards => [:fail, :succeed]
|
||||
end
|
||||
end
|
||||
|
||||
def fail
|
||||
false
|
||||
end
|
||||
|
||||
def succeed
|
||||
true
|
||||
end
|
||||
|
||||
def another_succeed
|
||||
true
|
||||
end
|
||||
|
||||
end
|
30
spec/unit/guard_spec.rb
Normal file
30
spec/unit/guard_spec.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe "per-transition guards" do
|
||||
let(:guardian) { Guardian.new }
|
||||
|
||||
it "allows the transition if the guard succeeds" do
|
||||
expect { guardian.use_one_guard_that_succeeds! }.to_not raise_error
|
||||
expect(guardian).to be_beta
|
||||
end
|
||||
|
||||
it "stops the transition if the guard fails" do
|
||||
expect { guardian.use_one_guard_that_fails! }.to raise_error(AASM::InvalidTransition)
|
||||
expect(guardian).to be_alpha
|
||||
end
|
||||
|
||||
it "allows the transition if all guards succeeds" do
|
||||
expect { guardian.use_guards_that_succeed! }.to_not raise_error
|
||||
expect(guardian).to be_beta
|
||||
end
|
||||
|
||||
it "stops the transition if the first guard fails" do
|
||||
expect { guardian.use_guards_where_the_first_fails! }.to raise_error(AASM::InvalidTransition)
|
||||
expect(guardian).to be_alpha
|
||||
end
|
||||
|
||||
it "stops the transition if the second guard fails" do
|
||||
expect { guardian.use_guards_where_the_second_fails! }.to raise_error(AASM::InvalidTransition)
|
||||
expect(guardian).to be_alpha
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue