aasm 4.5.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +2 -1
- data/CHANGELOG.md +13 -0
- data/LICENSE +1 -1
- data/README.md +25 -2
- data/aasm.gemspec +1 -0
- data/gemfiles/{rails_3.2.gemfile → rails_3.2_stable.gemfile} +2 -1
- data/lib/aasm/aasm.rb +14 -1
- data/lib/aasm/core/transition.rb +1 -1
- data/lib/aasm/persistence/active_record_persistence.rb +28 -10
- data/lib/aasm/persistence/base.rb +52 -25
- data/lib/aasm/version.rb +1 -1
- data/lib/generators/aasm/aasm_generator.rb +17 -0
- data/lib/generators/aasm/orm_helpers.rb +35 -0
- data/lib/generators/active_record/aasm_generator.rb +38 -0
- data/lib/generators/active_record/templates/migration.rb +8 -0
- data/lib/generators/active_record/templates/migration_existing.rb +9 -0
- data/lib/generators/mongoid/aasm_generator.rb +28 -0
- data/spec/database.rb +1 -1
- data/spec/generators/active_record_generator_spec.rb +39 -0
- data/spec/generators/mongoid_generator_spec.rb +33 -0
- data/spec/models/active_record/with_enum_without_column.rb +38 -0
- data/spec/models/guardian.rb +10 -0
- data/spec/models/silencer.rb +5 -0
- data/spec/unit/guard_spec.rb +12 -0
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +27 -0
- data/spec/unit/persistence/active_record_persistence_spec.rb +26 -0
- data/spec/unit/transition_spec.rb +2 -2
- metadata +30 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5b8d8a7ce2210a49761c9f1c622393a1bc453452
|
|
4
|
+
data.tar.gz: 1239b8468c521eb11bdbfef04d58540a6d1e5b72
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7b8f2affa363cce45636f684c24e2f72d71cb0a5af4fce0303894a77eb9db7fb37f08442c4b4b1955d7aaae042225ec4b3e52b27ffafe5cbb0c765c15498cf65
|
|
7
|
+
data.tar.gz: d9769d7cfd98b28e98f8a79c9b0b823cabec8b721bf5bdfaaae3dac37ca2b6127c38b42d427ed2fd451a67987c2371e36f4b46df09e0b4042fb1abb2c44320cd
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
|
@@ -11,12 +11,13 @@ rvm:
|
|
|
11
11
|
- 2.2
|
|
12
12
|
# - jruby-18mode # JRuby in 1.8 mode
|
|
13
13
|
- jruby-1.7 # JRuby in 1.9 mode
|
|
14
|
+
- jruby-9.0.3.0
|
|
14
15
|
- rbx-2.2.1
|
|
15
16
|
|
|
16
17
|
services: mongodb
|
|
17
18
|
|
|
18
19
|
gemfile:
|
|
19
|
-
- gemfiles/rails_3.
|
|
20
|
+
- gemfiles/rails_3.2_stable.gemfile
|
|
20
21
|
- gemfiles/rails_4.0.gemfile
|
|
21
22
|
- gemfiles/rails_4.0_mongo_mapper.gemfile
|
|
22
23
|
- gemfiles/rails_4.1.gemfile
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 4.6.0
|
|
4
|
+
|
|
5
|
+
* fix: make sure the column is actually present for _ActiveRecord_ enums (see [issue #265](https://github.com/aasm/aasm/issues/265) and [issue #152](https://github.com/aasm/aasm/issues/152) for details, thanks to [@anilmaurya](https://github.com/anilmaurya))
|
|
6
|
+
* add generators to configure active_record and mongoid after install (see [issue #261](https://github.com/aasm/aasm/issues/261) for details, thanks to [@anilmaurya](https://github.com/anilmaurya))
|
|
7
|
+
|
|
8
|
+
## 4.5.2
|
|
9
|
+
|
|
10
|
+
* fix arity difference between Procs and lambdas (see [issue #293](https://github.com/aasm/aasm/issues/293) for details)
|
|
11
|
+
|
|
12
|
+
## 4.5.1
|
|
13
|
+
|
|
14
|
+
* 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)
|
|
15
|
+
|
|
3
16
|
## 4.5.0
|
|
4
17
|
|
|
5
18
|
* add RSpec matchers `have_state`, `allow_event` and `allow_transition_to` (see [issue #147](https://github.com/aasm/aasm/issues/147) for details)
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -615,7 +615,7 @@ callback or the state update fails, all changes to any database record are rolle
|
|
|
615
615
|
Mongodb does not support transactions.
|
|
616
616
|
|
|
617
617
|
If you want to make sure a depending action happens only after the transaction is committed,
|
|
618
|
-
use the `after_commit` callback, like this:
|
|
618
|
+
use the `after_commit` callback along with the auto-save (bang) methods, like this:
|
|
619
619
|
|
|
620
620
|
```ruby
|
|
621
621
|
class Job < ActiveRecord::Base
|
|
@@ -634,6 +634,18 @@ class Job < ActiveRecord::Base
|
|
|
634
634
|
...
|
|
635
635
|
end
|
|
636
636
|
end
|
|
637
|
+
|
|
638
|
+
job = Job.where(state: 'sleeping').first!
|
|
639
|
+
job.run! # Saves the model and triggers the after_commit callback
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
Note that the following will not run the `after_commit` callbacks because
|
|
643
|
+
the auto-save method is not used:
|
|
644
|
+
|
|
645
|
+
```ruby
|
|
646
|
+
job = Job.where(state: 'sleeping').first!
|
|
647
|
+
job.run
|
|
648
|
+
job.save! #notify_about_running_job is not run
|
|
637
649
|
```
|
|
638
650
|
|
|
639
651
|
If you want to encapsulate state changes within an own transaction, the behavior
|
|
@@ -779,6 +791,17 @@ gem 'aasm'
|
|
|
779
791
|
% sudo gem install pkg/aasm-x.y.z.gem
|
|
780
792
|
```
|
|
781
793
|
|
|
794
|
+
### Generators
|
|
795
|
+
|
|
796
|
+
After installing Aasm you can run generator:
|
|
797
|
+
|
|
798
|
+
```sh
|
|
799
|
+
% rails generate aasm NAME [COLUMN_NAME]
|
|
800
|
+
```
|
|
801
|
+
Replace NAME with the Model name, COLUMN_NAME is optional(default is 'aasm_state').
|
|
802
|
+
This will create a model (if one does not exist) and configure it with aasm block.
|
|
803
|
+
For Active record orm a migration file is added to add aasm state column to table.
|
|
804
|
+
|
|
782
805
|
## Latest changes ##
|
|
783
806
|
|
|
784
807
|
Take a look at the [CHANGELOG](https://github.com/aasm/aasm/blob/master/CHANGELOG.md) for details about recent changes to the current version.
|
|
@@ -816,7 +839,7 @@ purpose.
|
|
|
816
839
|
|
|
817
840
|
## License ##
|
|
818
841
|
|
|
819
|
-
Copyright (c) 2006-
|
|
842
|
+
Copyright (c) 2006-2016 Scott Barron
|
|
820
843
|
|
|
821
844
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
822
845
|
a copy of this software and associated documentation files (the
|
data/aasm.gemspec
CHANGED
|
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.add_development_dependency 'rake'
|
|
20
20
|
s.add_development_dependency 'sdoc'
|
|
21
21
|
s.add_development_dependency 'rspec', ">= 3"
|
|
22
|
+
s.add_development_dependency 'generator_spec'
|
|
22
23
|
|
|
23
24
|
# debugging
|
|
24
25
|
# s.add_development_dependency 'debugger'
|
|
@@ -5,10 +5,11 @@ gem 'rubysl', :platforms => :rbx
|
|
|
5
5
|
gem 'rubinius-developer_tools', :platforms => :rbx
|
|
6
6
|
gem "jruby-openssl", :platforms => :jruby
|
|
7
7
|
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
8
|
-
gem "rails", "3
|
|
8
|
+
gem "rails", :github => "rails/rails", :branch => "3-2-stable"
|
|
9
9
|
gem 'mongoid', '~>3.1' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
|
|
10
10
|
gem 'sequel'
|
|
11
11
|
gem 'mongo_mapper', '~>0.13'
|
|
12
12
|
gem 'bson_ext', :platforms => :ruby
|
|
13
|
+
gem 'test-unit', '~> 3.0'
|
|
13
14
|
|
|
14
15
|
gemspec :path => "../"
|
data/lib/aasm/aasm.rb
CHANGED
|
@@ -39,7 +39,20 @@ module AASM
|
|
|
39
39
|
AASM::StateMachine[self][state_machine_name] ||= AASM::StateMachine.new(state_machine_name)
|
|
40
40
|
|
|
41
41
|
@aasm ||= {}
|
|
42
|
-
@aasm[state_machine_name]
|
|
42
|
+
if @aasm[state_machine_name]
|
|
43
|
+
# make sure to use provided options
|
|
44
|
+
options.each do |key, value|
|
|
45
|
+
@aasm[state_machine_name].state_machine.config.send("#{key}=", value)
|
|
46
|
+
end
|
|
47
|
+
else
|
|
48
|
+
# create a new base
|
|
49
|
+
@aasm[state_machine_name] = AASM::Base.new(
|
|
50
|
+
self,
|
|
51
|
+
state_machine_name,
|
|
52
|
+
AASM::StateMachine[self][state_machine_name],
|
|
53
|
+
options
|
|
54
|
+
)
|
|
55
|
+
end
|
|
43
56
|
@aasm[state_machine_name].instance_eval(&block) if block # new DSL
|
|
44
57
|
@aasm[state_machine_name]
|
|
45
58
|
end
|
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
|
|
@@ -96,7 +102,10 @@ module AASM
|
|
|
96
102
|
end
|
|
97
103
|
|
|
98
104
|
def aasm_column_looks_like_enum(name=:default)
|
|
99
|
-
self.class.
|
|
105
|
+
column_name = self.class.aasm(name).attribute_name.to_s
|
|
106
|
+
column = self.class.columns_hash[column_name]
|
|
107
|
+
raise NoMethodError.new("undefined method '#{column_name}' for #{self.class}") if column.nil?
|
|
108
|
+
column.type == :integer
|
|
100
109
|
end
|
|
101
110
|
|
|
102
111
|
def aasm_guess_enum_method(name=:default)
|
|
@@ -120,7 +129,7 @@ module AASM
|
|
|
120
129
|
end
|
|
121
130
|
|
|
122
131
|
# Ensures that if the aasm_state column is nil and the record is new
|
|
123
|
-
#
|
|
132
|
+
# then the initial state gets populated before validation on create
|
|
124
133
|
#
|
|
125
134
|
# foo = Foo.new
|
|
126
135
|
# foo.aasm_state # => nil
|
|
@@ -138,12 +147,17 @@ module AASM
|
|
|
138
147
|
AASM::StateMachine[self.class].keys.each do |state_machine_name|
|
|
139
148
|
# checking via respond_to? does not work in Rails <= 3
|
|
140
149
|
# 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
|
|
150
|
+
if aasm_column_is_blank?(state_machine_name)
|
|
142
151
|
aasm(state_machine_name).enter_initial_state
|
|
143
152
|
end
|
|
144
153
|
end
|
|
145
154
|
end
|
|
146
155
|
|
|
156
|
+
def aasm_column_is_blank?(state_machine_name)
|
|
157
|
+
attribute_name = self.class.aasm(state_machine_name).attribute_name
|
|
158
|
+
attribute_names.include?(attribute_name.to_s) && send(attribute_name).blank?
|
|
159
|
+
end
|
|
160
|
+
|
|
147
161
|
def aasm_fire_event(state_machine_name, name, options, *args, &block)
|
|
148
162
|
success = options[:persist] ? self.class.transaction(:requires_new => requires_new?(state_machine_name)) { super } : super
|
|
149
163
|
|
|
@@ -162,12 +176,16 @@ module AASM
|
|
|
162
176
|
def aasm_validate_states
|
|
163
177
|
AASM::StateMachine[self.class].keys.each do |state_machine_name|
|
|
164
178
|
unless aasm_skipping_validations(state_machine_name)
|
|
165
|
-
if
|
|
179
|
+
if aasm_invalid_state?(state_machine_name)
|
|
166
180
|
self.errors.add(AASM::StateMachine[self.class][state_machine_name].config.column , "is invalid")
|
|
167
181
|
end
|
|
168
182
|
end
|
|
169
183
|
end
|
|
170
184
|
end
|
|
185
|
+
|
|
186
|
+
def aasm_invalid_state?(state_machine_name)
|
|
187
|
+
aasm(state_machine_name).current_state && !aasm(state_machine_name).states.include?(aasm(state_machine_name).current_state)
|
|
188
|
+
end
|
|
171
189
|
end # InstanceMethods
|
|
172
190
|
|
|
173
191
|
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
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'rails/generators/named_base'
|
|
2
|
+
|
|
3
|
+
module AASM
|
|
4
|
+
module Generators
|
|
5
|
+
class AASMGenerator < Rails::Generators::NamedBase
|
|
6
|
+
|
|
7
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
8
|
+
argument :column_name, type: :string, default: 'aasm_state'
|
|
9
|
+
|
|
10
|
+
desc "Generates a model with the given NAME (if one does not exist) with aasm " <<
|
|
11
|
+
"block and migration to add aasm_state column."
|
|
12
|
+
|
|
13
|
+
hook_for :orm
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module AASM
|
|
2
|
+
module Generators
|
|
3
|
+
module OrmHelpers
|
|
4
|
+
|
|
5
|
+
def model_contents
|
|
6
|
+
if column_name == 'aasm_state'
|
|
7
|
+
<<RUBY
|
|
8
|
+
include AASM
|
|
9
|
+
|
|
10
|
+
aasm do
|
|
11
|
+
end
|
|
12
|
+
RUBY
|
|
13
|
+
else
|
|
14
|
+
<<RUBY
|
|
15
|
+
include AASM
|
|
16
|
+
|
|
17
|
+
aasm :column => '#{column_name}' do
|
|
18
|
+
end
|
|
19
|
+
RUBY
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def model_exists?
|
|
26
|
+
File.exists?(File.join(destination_root, model_path))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def model_path
|
|
30
|
+
@model_path ||= File.join("app", "models", "#{file_path}.rb")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'rails/generators/active_record'
|
|
2
|
+
require 'generators/aasm/orm_helpers'
|
|
3
|
+
|
|
4
|
+
module ActiveRecord
|
|
5
|
+
module Generators
|
|
6
|
+
class AASMGenerator < ActiveRecord::Generators::Base
|
|
7
|
+
include AASM::Generators::OrmHelpers
|
|
8
|
+
|
|
9
|
+
argument :column_name, type: :string, default: 'aasm_state'
|
|
10
|
+
|
|
11
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
12
|
+
|
|
13
|
+
def copy_aasm_migration
|
|
14
|
+
if model_exists?
|
|
15
|
+
migration_template "migration_existing.rb", "db/migrate/add_aasm_state_to_#{table_name}.rb"
|
|
16
|
+
else
|
|
17
|
+
migration_template "migration.rb", "db/migrate/aasm_create_#{table_name}.rb"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def generate_model
|
|
22
|
+
invoke "active_record:model", [name], migration: false unless model_exists?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def inject_aasm_content
|
|
26
|
+
content = model_contents
|
|
27
|
+
|
|
28
|
+
class_path = if namespaced?
|
|
29
|
+
class_name.to_s.split("::")
|
|
30
|
+
else
|
|
31
|
+
[class_name]
|
|
32
|
+
end
|
|
33
|
+
inject_into_class(model_path, class_path.last, content) if model_exists?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'rails/generators/named_base'
|
|
2
|
+
require 'generators/aasm/orm_helpers'
|
|
3
|
+
|
|
4
|
+
module Mongoid
|
|
5
|
+
module Generators
|
|
6
|
+
class AASMGenerator < Rails::Generators::NamedBase
|
|
7
|
+
include AASM::Generators::OrmHelpers
|
|
8
|
+
|
|
9
|
+
argument :column_name, type: :string, default: 'aasm_state'
|
|
10
|
+
|
|
11
|
+
def generate_model
|
|
12
|
+
invoke "mongoid:model", [name] unless model_exists?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def inject_aasm_content
|
|
16
|
+
inject_into_file model_path, model_contents, after: "include Mongoid::Document\n" if model_exists?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def inject_field_types
|
|
20
|
+
inject_into_file model_path, migration_data, after: "include Mongoid::Document\n" if model_exists?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def migration_data
|
|
24
|
+
" field :#{column_name}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/spec/database.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
ActiveRecord::Migration.suppress_messages do
|
|
2
|
-
%w{gates multiple_gates readers writers transients simples no_scopes multiple_no_scopes no_direct_assignments multiple_no_direct_assignments thieves multiple_thieves localizer_test_models persisted_states provided_and_persisted_states with_enums with_true_enums with_false_enums false_states multiple_with_enums multiple_with_true_enums multiple_with_false_enums multiple_false_states readme_jobs}.each do |table_name|
|
|
2
|
+
%w{gates multiple_gates readers writers transients simples no_scopes multiple_no_scopes no_direct_assignments multiple_no_direct_assignments thieves multiple_thieves localizer_test_models persisted_states provided_and_persisted_states with_enums with_enum_without_columns multiple_with_enum_without_columns with_true_enums with_false_enums false_states multiple_with_enums multiple_with_true_enums multiple_with_false_enums multiple_false_states readme_jobs}.each do |table_name|
|
|
3
3
|
ActiveRecord::Migration.create_table table_name, :force => true do |t|
|
|
4
4
|
t.string "aasm_state"
|
|
5
5
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'generator_spec'
|
|
3
|
+
require 'generators/active_record/aasm_generator'
|
|
4
|
+
|
|
5
|
+
describe ActiveRecord::Generators::AASMGenerator, type: :generator do
|
|
6
|
+
destination File.expand_path("../../../tmp", __FILE__)
|
|
7
|
+
|
|
8
|
+
before(:all) do
|
|
9
|
+
prepare_destination
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "creates model with aasm block for default column_name" do
|
|
13
|
+
run_generator %w(user)
|
|
14
|
+
assert_file "app/models/user.rb", /include AASM\n\n aasm do\n end\n/
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "creates model with aasm block for custom column_name" do
|
|
18
|
+
run_generator %w(user state)
|
|
19
|
+
assert_file "app/models/user.rb", /aasm :column => 'state' do\n end\n/
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "creates model with aasm block for namespaced model" do
|
|
23
|
+
run_generator %w(Admin::User state)
|
|
24
|
+
assert_file "app/models/admin/user.rb", /aasm :column => 'state' do\n end\n/
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "creates migration for model with aasm_column" do
|
|
28
|
+
run_generator %w(post)
|
|
29
|
+
assert_migration "db/migrate/aasm_create_posts.rb", /create_table(:posts) do |t|\n t.string :aasm_state\n/
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "add aasm_column in existing model" do
|
|
33
|
+
run_generator %w(job)
|
|
34
|
+
assert_file "app/models/job.rb"
|
|
35
|
+
run_generator %w(job)
|
|
36
|
+
assert_migration "db/migrate/add_aasm_state_to_jobs.rb"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'generator_spec'
|
|
3
|
+
require 'generators/mongoid/aasm_generator'
|
|
4
|
+
|
|
5
|
+
begin
|
|
6
|
+
require "mongoid"
|
|
7
|
+
|
|
8
|
+
describe Mongoid::Generators::AASMGenerator, type: :generator do
|
|
9
|
+
destination File.expand_path("../../../tmp", __FILE__)
|
|
10
|
+
|
|
11
|
+
before(:all) do
|
|
12
|
+
prepare_destination
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "creates model with aasm block for default column_name" do
|
|
16
|
+
run_generator %w(user)
|
|
17
|
+
assert_file "app/models/user.rb", /include AASM\n\n aasm do\n end\n/
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "creates model with aasm block for custom column_name" do
|
|
21
|
+
run_generator %w(user state)
|
|
22
|
+
assert_file "app/models/user.rb", /aasm :column => 'state' do\n end\n/
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "creates model with aasm block for namespaced model" do
|
|
26
|
+
run_generator %w(Admin::User state)
|
|
27
|
+
assert_file "app/models/admin/user.rb", /aasm :column => 'state' do\n end\n/
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
rescue LoadError
|
|
32
|
+
puts "Not running Mongoid specs because mongoid gem is not installed!!!"
|
|
33
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
class WithEnumWithoutColumn < ActiveRecord::Base
|
|
2
|
+
include AASM
|
|
3
|
+
|
|
4
|
+
if ActiveRecord::VERSION::MAJOR >= 4 && ActiveRecord::VERSION::MINOR >= 1 # won't work with Rails <= 4.1
|
|
5
|
+
enum status: {
|
|
6
|
+
opened: 0,
|
|
7
|
+
closed: 1
|
|
8
|
+
}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
aasm :column => :status do
|
|
12
|
+
state :closed, initial: true
|
|
13
|
+
state :opened
|
|
14
|
+
|
|
15
|
+
event :view do
|
|
16
|
+
transitions :to => :opened, :from => :closed
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class MultipleWithEnumWithoutColumn < ActiveRecord::Base
|
|
22
|
+
include AASM
|
|
23
|
+
if ActiveRecord::VERSION::MAJOR >= 4 && ActiveRecord::VERSION::MINOR >= 1 # won't work with Rails <= 4.1
|
|
24
|
+
enum status: {
|
|
25
|
+
opened: 0,
|
|
26
|
+
closed: 1
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
aasm :left, :column => :status do
|
|
31
|
+
state :closed, initial: true
|
|
32
|
+
state :opened
|
|
33
|
+
|
|
34
|
+
event :view do
|
|
35
|
+
transitions :to => :opened, :from => :closed
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
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/models/silencer.rb
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
class Silencer
|
|
2
2
|
include AASM
|
|
3
3
|
|
|
4
|
+
# yes, this line is here on purpose
|
|
5
|
+
# by this, we test if overriding configuration options works if
|
|
6
|
+
# the state machine is "re-opened"
|
|
7
|
+
aasm :whiny_transitions => true
|
|
8
|
+
|
|
4
9
|
aasm :whiny_transitions => false do
|
|
5
10
|
state :silent, :initial => true
|
|
6
11
|
state :crying
|
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
|
|
@@ -113,6 +113,20 @@ describe "instance methods" do
|
|
|
113
113
|
end
|
|
114
114
|
end
|
|
115
115
|
end
|
|
116
|
+
|
|
117
|
+
if ActiveRecord::VERSION::MAJOR >= 4 && ActiveRecord::VERSION::MINOR >= 1 # won't work with Rails <= 4.1
|
|
118
|
+
# Enum are introduced from Rails 4.1, therefore enum syntax will not work on Rails <= 4.1
|
|
119
|
+
context "when AASM enum setting is not enabled and aasm column not present" do
|
|
120
|
+
|
|
121
|
+
let(:multiple_with_enum_without_column) {MultipleWithEnumWithoutColumn.new}
|
|
122
|
+
|
|
123
|
+
it "should raise NoMethodError for transitions" do
|
|
124
|
+
expect{multiple_with_enum_without_column.send(:view, :left)}.to raise_error(NoMethodError, "undefined method 'status' for MultipleWithEnumWithoutColumn")
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
end
|
|
129
|
+
|
|
116
130
|
end
|
|
117
131
|
|
|
118
132
|
context "when AASM is configured to use enum" do
|
|
@@ -298,6 +312,19 @@ describe "named scopes with the new DSL" do
|
|
|
298
312
|
it "does not create scopes if requested" do
|
|
299
313
|
expect(MultipleNoScope).not_to respond_to(:pending)
|
|
300
314
|
end
|
|
315
|
+
|
|
316
|
+
context "result of scope" do
|
|
317
|
+
let!(:dsl1) { MultipleSimpleNewDsl.create!(status: :new) }
|
|
318
|
+
let!(:dsl2) { MultipleSimpleNewDsl.create!(status: :unknown_scope) }
|
|
319
|
+
|
|
320
|
+
after do
|
|
321
|
+
MultipleSimpleNewDsl.destroy_all
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "created scope works as where(name: :scope_name)" do
|
|
325
|
+
expect(MultipleSimpleNewDsl.unknown_scope).to contain_exactly(dsl2)
|
|
326
|
+
end
|
|
327
|
+
end
|
|
301
328
|
end # scopes
|
|
302
329
|
|
|
303
330
|
describe "direct assignment" do
|
|
@@ -113,6 +113,20 @@ describe "instance methods" do
|
|
|
113
113
|
end
|
|
114
114
|
end
|
|
115
115
|
end
|
|
116
|
+
|
|
117
|
+
if ActiveRecord::VERSION::MAJOR >= 4 && ActiveRecord::VERSION::MINOR >= 1 # won't work with Rails <= 4.1
|
|
118
|
+
# Enum are introduced from Rails 4.1, therefore enum syntax will not work on Rails <= 4.1
|
|
119
|
+
context "when AASM enum setting is not enabled and aasm column not present" do
|
|
120
|
+
|
|
121
|
+
let(:with_enum_without_column) {WithEnumWithoutColumn.new}
|
|
122
|
+
|
|
123
|
+
it "should raise NoMethodError for transitions" do
|
|
124
|
+
expect{with_enum_without_column.send(:view)}.to raise_error(NoMethodError, "undefined method 'status' for WithEnumWithoutColumn")
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
end
|
|
129
|
+
|
|
116
130
|
end
|
|
117
131
|
|
|
118
132
|
context "when AASM is configured to use enum" do
|
|
@@ -299,6 +313,18 @@ describe "named scopes with the new DSL" do
|
|
|
299
313
|
expect(NoScope).not_to respond_to(:pending)
|
|
300
314
|
end
|
|
301
315
|
|
|
316
|
+
context "result of scope" do
|
|
317
|
+
let!(:dsl1) { SimpleNewDsl.create!(status: :new) }
|
|
318
|
+
let!(:dsl2) { SimpleNewDsl.create!(status: :unknown_scope) }
|
|
319
|
+
|
|
320
|
+
after do
|
|
321
|
+
SimpleNewDsl.destroy_all
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "created scope works as where(name: :scope_name)" do
|
|
325
|
+
expect(SimpleNewDsl.unknown_scope).to contain_exactly(dsl2)
|
|
326
|
+
end
|
|
327
|
+
end
|
|
302
328
|
end # scopes
|
|
303
329
|
|
|
304
330
|
describe "direct assignment" do
|
|
@@ -31,7 +31,7 @@ describe 'transitions' do
|
|
|
31
31
|
expect(silencer).to be_smiling
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
it 'should call the block
|
|
34
|
+
it 'should call the block on success' do
|
|
35
35
|
silencer = Silencer.new
|
|
36
36
|
success = false
|
|
37
37
|
expect {
|
|
@@ -41,7 +41,7 @@ describe 'transitions' do
|
|
|
41
41
|
}.to change { success }.to(true)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
it 'should not call the block
|
|
44
|
+
it 'should not call the block on failure' do
|
|
45
45
|
silencer = Silencer.new
|
|
46
46
|
success = false
|
|
47
47
|
expect {
|
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.
|
|
4
|
+
version: 4.6.0
|
|
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-08 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: rake
|
|
@@ -54,6 +54,20 @@ dependencies:
|
|
|
54
54
|
- - ">="
|
|
55
55
|
- !ruby/object:Gem::Version
|
|
56
56
|
version: '3'
|
|
57
|
+
- !ruby/object:Gem::Dependency
|
|
58
|
+
name: generator_spec
|
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '0'
|
|
64
|
+
type: :development
|
|
65
|
+
prerelease: false
|
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - ">="
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '0'
|
|
57
71
|
- !ruby/object:Gem::Dependency
|
|
58
72
|
name: pry
|
|
59
73
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -90,7 +104,7 @@ files:
|
|
|
90
104
|
- Rakefile
|
|
91
105
|
- aasm.gemspec
|
|
92
106
|
- callbacks.txt
|
|
93
|
-
- gemfiles/rails_3.
|
|
107
|
+
- gemfiles/rails_3.2_stable.gemfile
|
|
94
108
|
- gemfiles/rails_4.0.gemfile
|
|
95
109
|
- gemfiles/rails_4.0_mongo_mapper.gemfile
|
|
96
110
|
- gemfiles/rails_4.1.gemfile
|
|
@@ -123,10 +137,18 @@ files:
|
|
|
123
137
|
- lib/aasm/rspec/transition_from.rb
|
|
124
138
|
- lib/aasm/state_machine.rb
|
|
125
139
|
- lib/aasm/version.rb
|
|
140
|
+
- lib/generators/aasm/aasm_generator.rb
|
|
141
|
+
- lib/generators/aasm/orm_helpers.rb
|
|
142
|
+
- lib/generators/active_record/aasm_generator.rb
|
|
143
|
+
- lib/generators/active_record/templates/migration.rb
|
|
144
|
+
- lib/generators/active_record/templates/migration_existing.rb
|
|
145
|
+
- lib/generators/mongoid/aasm_generator.rb
|
|
126
146
|
- spec/database.rb
|
|
127
147
|
- spec/database.yml
|
|
128
148
|
- spec/en.yml
|
|
129
149
|
- spec/en_deprecated_style.yml
|
|
150
|
+
- spec/generators/active_record_generator_spec.rb
|
|
151
|
+
- spec/generators/mongoid_generator_spec.rb
|
|
130
152
|
- spec/models/active_record/basic_active_record_two_state_machines_example.rb
|
|
131
153
|
- spec/models/active_record/complex_active_record_example.rb
|
|
132
154
|
- spec/models/active_record/derivate_new_dsl.rb
|
|
@@ -143,6 +165,7 @@ files:
|
|
|
143
165
|
- spec/models/active_record/thief.rb
|
|
144
166
|
- spec/models/active_record/transient.rb
|
|
145
167
|
- spec/models/active_record/with_enum.rb
|
|
168
|
+
- spec/models/active_record/with_enum_without_column.rb
|
|
146
169
|
- spec/models/active_record/with_false_enum.rb
|
|
147
170
|
- spec/models/active_record/with_true_enum.rb
|
|
148
171
|
- spec/models/active_record/writer.rb
|
|
@@ -256,7 +279,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
256
279
|
version: '0'
|
|
257
280
|
requirements: []
|
|
258
281
|
rubyforge_project:
|
|
259
|
-
rubygems_version: 2.
|
|
282
|
+
rubygems_version: 2.4.5
|
|
260
283
|
signing_key:
|
|
261
284
|
specification_version: 4
|
|
262
285
|
summary: State machine mixin for Ruby objects
|
|
@@ -265,6 +288,8 @@ test_files:
|
|
|
265
288
|
- spec/database.yml
|
|
266
289
|
- spec/en.yml
|
|
267
290
|
- spec/en_deprecated_style.yml
|
|
291
|
+
- spec/generators/active_record_generator_spec.rb
|
|
292
|
+
- spec/generators/mongoid_generator_spec.rb
|
|
268
293
|
- spec/models/active_record/basic_active_record_two_state_machines_example.rb
|
|
269
294
|
- spec/models/active_record/complex_active_record_example.rb
|
|
270
295
|
- spec/models/active_record/derivate_new_dsl.rb
|
|
@@ -281,6 +306,7 @@ test_files:
|
|
|
281
306
|
- spec/models/active_record/thief.rb
|
|
282
307
|
- spec/models/active_record/transient.rb
|
|
283
308
|
- spec/models/active_record/with_enum.rb
|
|
309
|
+
- spec/models/active_record/with_enum_without_column.rb
|
|
284
310
|
- spec/models/active_record/with_false_enum.rb
|
|
285
311
|
- spec/models/active_record/with_true_enum.rb
|
|
286
312
|
- spec/models/active_record/writer.rb
|