aasm 4.5.1 → 4.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/aasm/core/transition.rb +1 -1
- data/lib/aasm/persistence/active_record_persistence.rb +24 -9
- data/lib/aasm/persistence/base.rb +52 -25
- data/lib/aasm/version.rb +1 -1
- data/spec/models/guardian.rb +10 -0
- data/spec/unit/guard_spec.rb +12 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 497994639dac4183fdf996cafad384f308784855
|
4
|
+
data.tar.gz: 731e388e865ffb526e4cbb3c20443659aab8605a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3572795abc66917c392e8736afc6d8ea882b12f0fdfcb15cd8046ae0f1977e8dd01b2eeab5d2fcb7e659295c3f45b6aa438aa008c61c8707370be7b27b40e31
|
7
|
+
data.tar.gz: 42a4dc5b04c7a13e2a15e745a42b960a80cb4a90f4f62e1eb51c09b4493565314c85ae4aeeb1dd985fc85094706b440fc14ec11dbb7e7275c641e64309b7106d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 4.5.2
|
4
|
+
|
5
|
+
* fix arity difference between Procs and lambdas (see [issue #293](https://github.com/aasm/aasm/issues/293) for details)
|
6
|
+
|
3
7
|
## 4.5.1
|
4
8
|
|
5
9
|
* make sure to use override configuration options if state machine is defined more than once (see [issue #287](https://github.com/aasm/aasm/issues/287) for details)
|
data/lib/aasm/core/transition.rb
CHANGED
@@ -55,7 +55,7 @@ module AASM::Core
|
|
55
55
|
arity = record.send(:method, code.to_sym).arity
|
56
56
|
arity == 0 ? record.send(code) : record.send(code, *args)
|
57
57
|
when Proc
|
58
|
-
code.
|
58
|
+
code.parameters.size == 0 ? record.instance_exec(&code) : record.instance_exec(*args, &code)
|
59
59
|
when Array
|
60
60
|
if options[:guard]
|
61
61
|
# invoke guard callbacks
|
@@ -57,16 +57,12 @@ module AASM
|
|
57
57
|
|
58
58
|
success = if aasm_skipping_validations(name)
|
59
59
|
value = aasm_raw_attribute_value(state, name)
|
60
|
-
|
60
|
+
aasm_update_column(name, value)
|
61
61
|
else
|
62
62
|
self.save
|
63
63
|
end
|
64
|
-
unless success
|
65
|
-
write_attribute(self.class.aasm(name).attribute_name, old_value)
|
66
|
-
return false
|
67
|
-
end
|
68
64
|
|
69
|
-
true
|
65
|
+
success ? true : aasm_rollback(name, old_value)
|
70
66
|
end
|
71
67
|
|
72
68
|
# Writes <tt>state</tt> to the state column, but does not persist it to the database
|
@@ -86,6 +82,16 @@ module AASM
|
|
86
82
|
end
|
87
83
|
|
88
84
|
private
|
85
|
+
|
86
|
+
def aasm_update_column(name, value)
|
87
|
+
self.class.where(self.class.primary_key => self.id).update_all(self.class.aasm(name).attribute_name => value) == 1
|
88
|
+
end
|
89
|
+
|
90
|
+
def aasm_rollback(name, old_value)
|
91
|
+
write_attribute(self.class.aasm(name).attribute_name, old_value)
|
92
|
+
false
|
93
|
+
end
|
94
|
+
|
89
95
|
def aasm_enum(name=:default)
|
90
96
|
case AASM::StateMachine[self.class][name].config.enum
|
91
97
|
when false then nil
|
@@ -120,7 +126,7 @@ module AASM
|
|
120
126
|
end
|
121
127
|
|
122
128
|
# Ensures that if the aasm_state column is nil and the record is new
|
123
|
-
#
|
129
|
+
# then the initial state gets populated before validation on create
|
124
130
|
#
|
125
131
|
# foo = Foo.new
|
126
132
|
# foo.aasm_state # => nil
|
@@ -138,12 +144,17 @@ module AASM
|
|
138
144
|
AASM::StateMachine[self.class].keys.each do |state_machine_name|
|
139
145
|
# checking via respond_to? does not work in Rails <= 3
|
140
146
|
# if respond_to?(self.class.aasm(state_machine_name).attribute_name) && send(self.class.aasm(state_machine_name).attribute_name).blank? # Rails 4
|
141
|
-
if
|
147
|
+
if aasm_column_is_blank?(state_machine_name)
|
142
148
|
aasm(state_machine_name).enter_initial_state
|
143
149
|
end
|
144
150
|
end
|
145
151
|
end
|
146
152
|
|
153
|
+
def aasm_column_is_blank?(state_machine_name)
|
154
|
+
attribute_name = self.class.aasm(state_machine_name).attribute_name
|
155
|
+
attribute_names.include?(attribute_name.to_s) && send(attribute_name).blank?
|
156
|
+
end
|
157
|
+
|
147
158
|
def aasm_fire_event(state_machine_name, name, options, *args, &block)
|
148
159
|
success = options[:persist] ? self.class.transaction(:requires_new => requires_new?(state_machine_name)) { super } : super
|
149
160
|
|
@@ -162,12 +173,16 @@ module AASM
|
|
162
173
|
def aasm_validate_states
|
163
174
|
AASM::StateMachine[self.class].keys.each do |state_machine_name|
|
164
175
|
unless aasm_skipping_validations(state_machine_name)
|
165
|
-
if
|
176
|
+
if aasm_invalid_state?(state_machine_name)
|
166
177
|
self.errors.add(AASM::StateMachine[self.class][state_machine_name].config.column , "is invalid")
|
167
178
|
end
|
168
179
|
end
|
169
180
|
end
|
170
181
|
end
|
182
|
+
|
183
|
+
def aasm_invalid_state?(state_machine_name)
|
184
|
+
aasm(state_machine_name).current_state && !aasm(state_machine_name).states.include?(aasm(state_machine_name).current_state)
|
185
|
+
end
|
171
186
|
end # InstanceMethods
|
172
187
|
|
173
188
|
end
|
@@ -55,35 +55,62 @@ module AASM
|
|
55
55
|
# make sure to create a (named) scope for each state
|
56
56
|
def state_with_scope(name, *args)
|
57
57
|
state_without_scope(name, *args)
|
58
|
-
if
|
58
|
+
create_scope(name) if create_scope?(name)
|
59
|
+
end
|
60
|
+
alias_method :state_without_scope, :state
|
61
|
+
alias_method :state, :state_with_scope
|
59
62
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
66
|
-
else
|
67
|
-
@klass.class_eval do
|
68
|
-
named_scope name, :conditions => conditions
|
69
|
-
end
|
70
|
-
end
|
71
|
-
elsif @klass.ancestors.map {|klass| klass.to_s}.include?("Mongoid::Document")
|
72
|
-
klass = @klass
|
73
|
-
state_machine_name = @name
|
74
|
-
scope_options = lambda {
|
75
|
-
klass.send(:where, {klass.aasm(state_machine_name).attribute_name.to_sym => name.to_s})
|
76
|
-
}
|
77
|
-
@klass.send(:scope, name, scope_options)
|
78
|
-
elsif @klass.ancestors.map {|klass| klass.to_s}.include?("MongoMapper::Document")
|
79
|
-
conditions = { @klass.aasm(@name).attribute_name.to_sym => name.to_s }
|
80
|
-
@klass.scope(name, lambda { @klass.where(conditions) })
|
81
|
-
end
|
63
|
+
private
|
64
|
+
|
65
|
+
def create_scope?(name)
|
66
|
+
@state_machine.config.create_scopes && !@klass.respond_to?(name)
|
67
|
+
end
|
82
68
|
|
69
|
+
def create_scope(name)
|
70
|
+
if ancestors_include?("ActiveRecord::Base")
|
71
|
+
create_for_active_record(name)
|
72
|
+
elsif ancestors_include?("Mongoid::Document")
|
73
|
+
create_for_mongoid(name)
|
74
|
+
elsif ancestors_include?("MongoMapper::Document")
|
75
|
+
create_for_mongomapper(name)
|
83
76
|
end
|
84
77
|
end
|
85
|
-
|
86
|
-
|
78
|
+
|
79
|
+
def ancestors_include?(class_name)
|
80
|
+
@klass.ancestors.map { |klass| klass.to_s }.include?(class_name)
|
81
|
+
end
|
82
|
+
|
83
|
+
def create_for_active_record(name)
|
84
|
+
conditions = {
|
85
|
+
"#{@klass.table_name}.#{@klass.aasm(@name).attribute_name}" => name.to_s
|
86
|
+
}
|
87
|
+
if ActiveRecord::VERSION::MAJOR >= 3
|
88
|
+
@klass.class_eval do
|
89
|
+
scope name, lambda { where(conditions) }
|
90
|
+
end
|
91
|
+
else
|
92
|
+
@klass.class_eval do
|
93
|
+
named_scope name, :conditions => conditions
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def create_for_mongoid(name)
|
99
|
+
klass = @klass
|
100
|
+
state_machine_name = @name
|
101
|
+
scope_options = lambda {
|
102
|
+
klass.send(
|
103
|
+
:where,
|
104
|
+
{ klass.aasm(state_machine_name).attribute_name.to_sym => name.to_s }
|
105
|
+
)
|
106
|
+
}
|
107
|
+
@klass.send(:scope, name, scope_options)
|
108
|
+
end
|
109
|
+
|
110
|
+
def create_for_mongomapper(name)
|
111
|
+
conditions = { @klass.aasm(@name).attribute_name.to_sym => name.to_s }
|
112
|
+
@klass.scope(name, lambda { @klass.where(conditions) })
|
113
|
+
end
|
87
114
|
end # Base
|
88
115
|
|
89
116
|
end # AASM
|
data/lib/aasm/version.rb
CHANGED
data/spec/models/guardian.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
class Guardian
|
2
2
|
include AASM
|
3
3
|
|
4
|
+
def inner_guard(options={})
|
5
|
+
end
|
6
|
+
|
4
7
|
aasm do
|
5
8
|
state :alpha, :initial => true
|
6
9
|
state :beta
|
@@ -12,6 +15,13 @@ class Guardian
|
|
12
15
|
transitions :from => :alpha, :to => :beta, :guard => :fail
|
13
16
|
end
|
14
17
|
|
18
|
+
event :use_proc_guard_with_params do
|
19
|
+
transitions :from => :alpha, :to => :beta, :guard => Proc.new { |options={}| inner_guard(options) }
|
20
|
+
end
|
21
|
+
event :use_lambda_guard_with_params do
|
22
|
+
transitions :from => :alpha, :to => :beta, :guard => lambda { |options={}| inner_guard(options) }
|
23
|
+
end
|
24
|
+
|
15
25
|
event :use_guards_that_succeed do
|
16
26
|
transitions :from => :alpha, :to => :beta, :guards => [:succeed, :another_succeed]
|
17
27
|
end
|
data/spec/unit/guard_spec.rb
CHANGED
@@ -27,6 +27,18 @@ describe "per-transition guards" do
|
|
27
27
|
expect { guardian.use_guards_where_the_second_fails! }.to raise_error(AASM::InvalidTransition)
|
28
28
|
expect(guardian).to be_alpha
|
29
29
|
end
|
30
|
+
|
31
|
+
describe "with params" do
|
32
|
+
it "using a Proc" do
|
33
|
+
expect(guardian).to receive(:inner_guard).with({:flag => true}).and_return(true)
|
34
|
+
guardian.use_proc_guard_with_params(:flag => true)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "using a lambda" do
|
38
|
+
expect(guardian).to receive(:inner_guard).with({:flag => true}).and_return(true)
|
39
|
+
guardian.use_lambda_guard_with_params(:flag => true)
|
40
|
+
end
|
41
|
+
end
|
30
42
|
end
|
31
43
|
|
32
44
|
describe "event guards" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aasm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.5.
|
4
|
+
version: 4.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Barron
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2016-01-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake
|