aasm 4.0.5 → 4.1.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/.travis.yml +10 -11
- data/CHANGELOG.md +18 -1
- data/Gemfile +6 -2
- data/README.md +21 -4
- data/README_FROM_VERSION_3_TO_4.md +1 -1
- data/aasm.gemspec +5 -2
- data/gemfiles/rails_3.2.gemfile +3 -1
- data/gemfiles/rails_4.0.gemfile +2 -5
- data/gemfiles/rails_4.0_bson1.gemfile +14 -0
- data/gemfiles/rails_4.1.gemfile +2 -5
- data/gemfiles/rails_4.1_bson1.gemfile +14 -0
- data/gemfiles/rails_4.2.gemfile +13 -0
- data/gemfiles/rails_4.2_bson1.gemfile +14 -0
- data/lib/aasm/aasm.rb +1 -1
- data/lib/aasm/base.rb +7 -7
- data/lib/aasm/core/event.rb +10 -2
- data/lib/aasm/core/transition.rb +0 -2
- data/lib/aasm/instance_base.rb +1 -1
- data/lib/aasm/persistence/active_record_persistence.rb +4 -4
- data/lib/aasm/persistence/base.rb +4 -1
- data/lib/aasm/persistence/mongo_mapper_persistence.rb +174 -0
- data/lib/aasm/persistence/mongoid_persistence.rb +1 -5
- data/lib/aasm/persistence.rb +2 -0
- data/lib/aasm/version.rb +1 -1
- data/spec/database.rb +1 -1
- data/spec/models/callbacks/basic.rb +33 -20
- data/spec/models/callbacks/private_method.rb +44 -0
- data/spec/models/callbacks/with_args.rb +20 -4
- data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +10 -0
- data/spec/models/mongo_mapper/simple_mongo_mapper.rb +11 -0
- data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +12 -0
- data/spec/models/mongoid/simple_new_dsl_mongoid.rb +1 -1
- data/spec/models/persistence.rb +18 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/unit/callbacks_spec.rb +68 -32
- data/spec/unit/complex_example_spec.rb +9 -9
- data/spec/unit/event_spec.rb +6 -6
- data/spec/unit/inspection_spec.rb +2 -2
- data/spec/unit/persistence/active_record_persistence_spec.rb +38 -39
- data/spec/unit/persistence/mongo_mapper_persistance_spec.rb +135 -0
- data/spec/unit/persistence/mongoid_persistance_spec.rb +4 -10
- data/spec/unit/persistence/sequel_persistence_spec.rb +2 -1
- data/spec/unit/subclassing_spec.rb +1 -1
- data/spec/unit/transition_spec.rb +10 -10
- metadata +21 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a07996d6cd3f0270a6ec9d010a904cebd462b6a7
|
|
4
|
+
data.tar.gz: 57e8efc5d284371e23c50d41771beb3172787bdd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0e1f53507bcbcf9deecce7193a5fed9f37ae5fbc91b6325f127820ead35113e19bea7dba6f87af9482affac31462b05e1b6c89a87ef61a47ad93d95c07f19179
|
|
7
|
+
data.tar.gz: 9da9eea4b58047190c441dc42c120fed864c318828340cc61505601f70179736d9cc70a0f60166bae13c6fc6aa3f3c8c4569047915a0af72ab152f30ce5422fd
|
data/.travis.yml
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
sudo: false
|
|
1
2
|
language: ruby
|
|
3
|
+
cache: bundler
|
|
2
4
|
|
|
3
5
|
rvm:
|
|
4
6
|
# - 1.8.7
|
|
5
|
-
- 1.9.2
|
|
7
|
+
# - 1.9.2
|
|
6
8
|
- 1.9.3
|
|
7
9
|
- 2.0.0
|
|
8
10
|
- 2.1
|
|
11
|
+
- 2.2
|
|
9
12
|
# - jruby-18mode # JRuby in 1.8 mode
|
|
10
|
-
- jruby-
|
|
13
|
+
- jruby-1.7 # JRuby in 1.9 mode
|
|
11
14
|
- rbx-2.2.1
|
|
12
15
|
|
|
13
16
|
services: mongodb
|
|
@@ -15,21 +18,17 @@ services: mongodb
|
|
|
15
18
|
gemfile:
|
|
16
19
|
- gemfiles/rails_3.2.gemfile
|
|
17
20
|
- gemfiles/rails_4.0.gemfile
|
|
21
|
+
- gemfiles/rails_4.0_bson1.gemfile
|
|
18
22
|
- gemfiles/rails_4.1.gemfile
|
|
23
|
+
- gemfiles/rails_4.1_bson1.gemfile
|
|
24
|
+
- gemfiles/rails_4.2.gemfile
|
|
25
|
+
- gemfiles/rails_4.2_bson1.gemfile
|
|
19
26
|
|
|
20
27
|
matrix:
|
|
21
28
|
allow_failures:
|
|
22
29
|
- rvm: rbx-2.2.1
|
|
23
|
-
- rvm: jruby-
|
|
30
|
+
- rvm: jruby-1.7
|
|
24
31
|
exclude:
|
|
25
|
-
- rvm: 1.8.7
|
|
26
|
-
gemfile: gemfiles/rails_4.0.gemfile
|
|
27
|
-
- rvm: 1.8.7
|
|
28
|
-
gemfile: gemfiles/rails_4.1.gemfile
|
|
29
|
-
- rvm: 1.9.2
|
|
30
|
-
gemfile: gemfiles/rails_4.0.gemfile
|
|
31
|
-
- rvm: 1.9.2
|
|
32
|
-
gemfile: gemfiles/rails_4.1.gemfile
|
|
33
32
|
- rvm: 1.9.3
|
|
34
33
|
gemfile: gemfiles/rails_4.1.gemfile
|
|
35
34
|
- rvm: jruby-19mode
|
data/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
-
## 4.
|
|
3
|
+
## 4.2.0 (not yet released)
|
|
4
4
|
|
|
5
|
+
## 4.1.0
|
|
6
|
+
|
|
7
|
+
* bugfix: initialize the aasm state column after initialization of the _Mongoid_ instance (see [issue #206](https://github.com/aasm/aasm/issues/206), thanks to [@Shwetakale ](https://github.com/Shwetakale ))
|
|
8
|
+
* added support for mongomapper ORM (see [issue #203](https://github.com/aasm/aasm/issues/203), thanks to [@reidmorrison ](https://github.com/reidmorrison ))
|
|
5
9
|
* `aasm_column` has been removed. Use `aasm.attribute_name` instead
|
|
6
10
|
* `aasm_human_event_name` has been removed. Use `aasm.human_event_name` instead
|
|
7
11
|
|
|
12
|
+
## 4.0.8
|
|
13
|
+
|
|
14
|
+
* bugfix: may_event_name? should return true or false only (see [issue #200](https://github.com/aasm/aasm/issues/200) for details)
|
|
15
|
+
|
|
16
|
+
## 4.0.7
|
|
17
|
+
|
|
18
|
+
* bugfix: take private methods into account when checking for callbacks (see [issue #197](https://github.com/aasm/aasm/issues/197) for details)
|
|
19
|
+
|
|
20
|
+
## 4.0.6
|
|
21
|
+
|
|
22
|
+
* bugfix: `false` is treated as uninitialised state (same as `nil`) (see [issue #195](https://github.com/aasm/aasm/issues/195) for details)
|
|
23
|
+
* bugfix: an event's `:error` callback now retrieves all arguments passed to the event (see [issue #196](https://github.com/aasm/aasm/issues/196) for details)
|
|
24
|
+
|
|
8
25
|
## 4.0.5
|
|
9
26
|
|
|
10
27
|
* bugfix: initialize the aasm state column after initialization of the _ActiveRecord_ instance only if the attribute has been loaded (see [issue #193](https://github.com/aasm/aasm/issues/193) for details)
|
data/Gemfile
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
source "https://rubygems.org"
|
|
2
2
|
|
|
3
3
|
gem "sqlite3", :platforms => :ruby
|
|
4
|
-
gem "coveralls"
|
|
4
|
+
gem "coveralls"
|
|
5
5
|
gem 'rubysl', :platforms => :rbx
|
|
6
6
|
gem "jruby-openssl", :platforms => :jruby
|
|
7
7
|
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
8
8
|
gem "rails", "~>4.1"
|
|
9
|
-
gem 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
|
|
9
|
+
gem 'mongoid', '~>4.0' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
|
|
10
10
|
gem 'sequel'
|
|
11
|
+
# Since mongoid V4 requires incompatible bson V2, cannot have mongoid (V4 or greater)
|
|
12
|
+
# and mongo_mapper ( or mongo ) in the same application
|
|
13
|
+
#gem 'mongo_mapper', '~> 0.13'
|
|
14
|
+
#gem 'bson_ext', :platforms => :ruby
|
|
11
15
|
|
|
12
16
|
gemspec
|
data/README.md
CHANGED
|
@@ -9,8 +9,8 @@ This package contains AASM, a library for adding finite state machines to Ruby c
|
|
|
9
9
|
|
|
10
10
|
AASM started as the *acts_as_state_machine* plugin but has evolved into a more generic library
|
|
11
11
|
that no longer targets only ActiveRecord models. It currently provides adapters for
|
|
12
|
-
[ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html)
|
|
13
|
-
[Mongoid](http://mongoid.org/), but it can be used for any Ruby class, no matter what
|
|
12
|
+
[ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html),
|
|
13
|
+
[Mongoid](http://mongoid.org/), and [Mongomapper](http://mongomapper.com/) but it can be used for any Ruby class, no matter what
|
|
14
14
|
parent class it has (if any).
|
|
15
15
|
|
|
16
16
|
## Upgrade from version 3 to 4
|
|
@@ -435,7 +435,7 @@ to ```false```.
|
|
|
435
435
|
|
|
436
436
|
### Sequel
|
|
437
437
|
|
|
438
|
-
AASM also supports [Sequel](http://sequel.jeremyevans.net/) besides _ActiveRecord_ and
|
|
438
|
+
AASM also supports [Sequel](http://sequel.jeremyevans.net/) besides _ActiveRecord_, _Mongoid_, and _MongoMapper_.
|
|
439
439
|
|
|
440
440
|
```ruby
|
|
441
441
|
class Job < Sequel::Model
|
|
@@ -466,6 +466,23 @@ class Job
|
|
|
466
466
|
end
|
|
467
467
|
```
|
|
468
468
|
|
|
469
|
+
### MongoMapper
|
|
470
|
+
|
|
471
|
+
AASM also supports persistence to Mongodb if you're using MongoMapper. Make sure
|
|
472
|
+
to include MongoMapper::Document before you include AASM.
|
|
473
|
+
|
|
474
|
+
```ruby
|
|
475
|
+
class Job
|
|
476
|
+
include MongoMapper::Document
|
|
477
|
+
include AASM
|
|
478
|
+
|
|
479
|
+
key :aasm_state, Symbol
|
|
480
|
+
aasm do
|
|
481
|
+
...
|
|
482
|
+
end
|
|
483
|
+
end
|
|
484
|
+
```
|
|
485
|
+
|
|
469
486
|
### Automatic Scopes
|
|
470
487
|
|
|
471
488
|
AASM will automatically create scope methods for each state in the model.
|
|
@@ -671,7 +688,7 @@ purpose.
|
|
|
671
688
|
|
|
672
689
|
## License ##
|
|
673
690
|
|
|
674
|
-
Copyright (c) 2006-
|
|
691
|
+
Copyright (c) 2006-2015 Scott Barron
|
|
675
692
|
|
|
676
693
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
677
694
|
a copy of this software and associated documentation files (the
|
data/aasm.gemspec
CHANGED
|
@@ -9,13 +9,16 @@ Gem::Specification.new do |s|
|
|
|
9
9
|
s.email = %q{scott@elitists.net, ttilley@gmail.com, aasm@mt7.de}
|
|
10
10
|
s.homepage = %q{https://github.com/aasm/aasm}
|
|
11
11
|
s.summary = %q{State machine mixin for Ruby objects}
|
|
12
|
-
s.description = %q{AASM is a continuation of the acts
|
|
12
|
+
s.description = %q{AASM is a continuation of the acts-as-state-machine rails plugin, built for plain Ruby objects.}
|
|
13
13
|
s.date = Time.now
|
|
14
14
|
s.licenses = ["MIT"]
|
|
15
15
|
|
|
16
|
+
s.platform = Gem::Platform::RUBY
|
|
17
|
+
s.required_ruby_version = '>= 1.9.3'
|
|
18
|
+
|
|
16
19
|
s.add_development_dependency 'rake'
|
|
17
20
|
s.add_development_dependency 'sdoc'
|
|
18
|
-
s.add_development_dependency 'rspec'
|
|
21
|
+
s.add_development_dependency 'rspec'
|
|
19
22
|
|
|
20
23
|
# debugging
|
|
21
24
|
# s.add_development_dependency 'debugger'
|
data/gemfiles/rails_3.2.gemfile
CHANGED
|
@@ -7,7 +7,9 @@ gem 'rubinius-developer_tools', :platforms => :rbx
|
|
|
7
7
|
gem "jruby-openssl", :platforms => :jruby
|
|
8
8
|
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
9
9
|
gem "rails", "3.2.21"
|
|
10
|
-
gem 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
|
|
10
|
+
gem 'mongoid', '~>3.1' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
|
|
11
11
|
gem 'sequel'
|
|
12
|
+
gem 'mongo_mapper', '~>0.13'
|
|
13
|
+
gem 'bson_ext', :platforms => :ruby
|
|
12
14
|
|
|
13
15
|
gemspec :path => "../"
|
data/gemfiles/rails_4.0.gemfile
CHANGED
|
@@ -6,11 +6,8 @@ gem 'rubysl', :platforms => :rbx
|
|
|
6
6
|
gem 'rubinius-developer_tools', :platforms => :rbx
|
|
7
7
|
gem "jruby-openssl", :platforms => :jruby
|
|
8
8
|
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
9
|
-
gem "rails", "4.0.
|
|
10
|
-
|
|
11
|
-
# mongoid is not yet compatible with Rails >= 4
|
|
12
|
-
# gem 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
|
|
13
|
-
|
|
9
|
+
gem "rails", "4.0.13"
|
|
10
|
+
gem 'mongoid', '~>4.0' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
|
|
14
11
|
gem 'sequel'
|
|
15
12
|
|
|
16
13
|
gemspec :path => "../"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gem "sqlite3", :platforms => :ruby
|
|
4
|
+
gem "coveralls"
|
|
5
|
+
gem 'rubysl', :platforms => :rbx
|
|
6
|
+
gem 'rubinius-developer_tools', :platforms => :rbx
|
|
7
|
+
gem "jruby-openssl", :platforms => :jruby
|
|
8
|
+
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
9
|
+
gem "rails", "4.0.13"
|
|
10
|
+
gem 'sequel'
|
|
11
|
+
gem 'mongo_mapper', '~>0.13'
|
|
12
|
+
gem 'bson_ext', :platforms => :ruby
|
|
13
|
+
|
|
14
|
+
gemspec :path => "../"
|
data/gemfiles/rails_4.1.gemfile
CHANGED
|
@@ -6,11 +6,8 @@ gem 'rubysl', :platforms => :rbx
|
|
|
6
6
|
gem 'rubinius-developer_tools', :platforms => :rbx
|
|
7
7
|
gem "jruby-openssl", :platforms => :jruby
|
|
8
8
|
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
9
|
-
gem "rails", "4.1.
|
|
10
|
-
|
|
11
|
-
# mongoid is not yet compatible with Rails >= 4
|
|
12
|
-
# gem 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
|
|
13
|
-
|
|
9
|
+
gem "rails", "4.1.9"
|
|
10
|
+
gem 'mongoid', '~>4.0' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
|
|
14
11
|
gem 'sequel'
|
|
15
12
|
|
|
16
13
|
gemspec :path => "../"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gem "sqlite3", :platforms => :ruby
|
|
4
|
+
gem "coveralls"
|
|
5
|
+
gem 'rubysl', :platforms => :rbx
|
|
6
|
+
gem 'rubinius-developer_tools', :platforms => :rbx
|
|
7
|
+
gem "jruby-openssl", :platforms => :jruby
|
|
8
|
+
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
9
|
+
gem "rails", "4.1.9"
|
|
10
|
+
gem 'sequel'
|
|
11
|
+
gem 'mongo_mapper', '~> 0.13'
|
|
12
|
+
gem 'bson_ext', :platforms => :ruby
|
|
13
|
+
|
|
14
|
+
gemspec :path => "../"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gem "sqlite3", :platforms => :ruby
|
|
4
|
+
gem "coveralls"
|
|
5
|
+
gem 'rubysl', :platforms => :rbx
|
|
6
|
+
gem 'rubinius-developer_tools', :platforms => :rbx
|
|
7
|
+
gem "jruby-openssl", :platforms => :jruby
|
|
8
|
+
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
9
|
+
gem "rails", "4.2.0"
|
|
10
|
+
gem 'mongoid', '~>4.0' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
|
|
11
|
+
gem 'sequel'
|
|
12
|
+
|
|
13
|
+
gemspec :path => "../"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gem "sqlite3", :platforms => :ruby
|
|
4
|
+
gem "coveralls"
|
|
5
|
+
gem 'rubysl', :platforms => :rbx
|
|
6
|
+
gem 'rubinius-developer_tools', :platforms => :rbx
|
|
7
|
+
gem "jruby-openssl", :platforms => :jruby
|
|
8
|
+
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
9
|
+
gem "rails", "4.2.0"
|
|
10
|
+
gem 'sequel'
|
|
11
|
+
gem 'mongo_mapper'
|
|
12
|
+
gem 'bson_ext', :platforms => :ruby
|
|
13
|
+
|
|
14
|
+
gemspec :path => "../"
|
data/lib/aasm/aasm.rb
CHANGED
data/lib/aasm/base.rb
CHANGED
|
@@ -56,12 +56,12 @@ module AASM
|
|
|
56
56
|
def state(name, options={})
|
|
57
57
|
@state_machine.add_state(name, @klass, options)
|
|
58
58
|
|
|
59
|
-
@klass.send(:define_method, "#{name
|
|
59
|
+
@klass.send(:define_method, "#{name}?") do
|
|
60
60
|
aasm.current_state == name
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
unless @klass.const_defined?("STATE_#{name.
|
|
64
|
-
@klass.const_set("STATE_#{name.
|
|
63
|
+
unless @klass.const_defined?("STATE_#{name.upcase}")
|
|
64
|
+
@klass.const_set("STATE_#{name.upcase}", name)
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
|
|
@@ -72,16 +72,16 @@ module AASM
|
|
|
72
72
|
# an addition over standard aasm so that, before firing an event, you can ask
|
|
73
73
|
# may_event? and get back a boolean that tells you whether the guard method
|
|
74
74
|
# on the transition will let this happen.
|
|
75
|
-
@klass.send(:define_method, "may_#{name
|
|
75
|
+
@klass.send(:define_method, "may_#{name}?") do |*args|
|
|
76
76
|
aasm.may_fire_event?(name, *args)
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
@klass.send(:define_method, "#{name
|
|
80
|
-
aasm.current_event = "#{name
|
|
79
|
+
@klass.send(:define_method, "#{name}!") do |*args, &block|
|
|
80
|
+
aasm.current_event = "#{name}!".to_sym
|
|
81
81
|
aasm_fire_event(name, {:persist => true}, *args, &block)
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
@klass.send(:define_method, "#{name
|
|
84
|
+
@klass.send(:define_method, "#{name}") do |*args, &block|
|
|
85
85
|
aasm.current_event = name.to_sym
|
|
86
86
|
aasm_fire_event(name, {:persist => false}, *args, &block)
|
|
87
87
|
end
|
data/lib/aasm/core/event.rb
CHANGED
|
@@ -124,14 +124,22 @@ module AASM::Core
|
|
|
124
124
|
def invoke_callbacks(code, record, args)
|
|
125
125
|
case code
|
|
126
126
|
when Symbol, String
|
|
127
|
-
record.
|
|
127
|
+
unless record.respond_to?(code, true)
|
|
128
|
+
raise NoMethodError.new("NoMethodError: undefined method `#{code}' for #{record.inspect}:#{record.class}")
|
|
129
|
+
end
|
|
130
|
+
arity = record.send(:method, code.to_sym).arity
|
|
131
|
+
record.send(code, *(arity < 0 ? args : args[0...arity]))
|
|
128
132
|
true
|
|
133
|
+
|
|
129
134
|
when Proc
|
|
130
|
-
|
|
135
|
+
arity = code.arity
|
|
136
|
+
record.instance_exec(*(arity < 0 ? args : args[0...arity]), &code)
|
|
131
137
|
true
|
|
138
|
+
|
|
132
139
|
when Array
|
|
133
140
|
code.each {|a| invoke_callbacks(a, record, args)}
|
|
134
141
|
true
|
|
142
|
+
|
|
135
143
|
else
|
|
136
144
|
false
|
|
137
145
|
end
|
data/lib/aasm/core/transition.rb
CHANGED
|
@@ -50,11 +50,9 @@ module AASM::Core
|
|
|
50
50
|
|
|
51
51
|
case code
|
|
52
52
|
when Symbol, String
|
|
53
|
-
# QUESTION : record.send(code, *args) ?
|
|
54
53
|
arity = record.send(:method, code.to_sym).arity
|
|
55
54
|
arity == 0 ? record.send(code) : record.send(code, *args)
|
|
56
55
|
when Proc
|
|
57
|
-
# QUESTION : record.instance_exec(*args, &code) ?
|
|
58
56
|
code.arity == 0 ? record.instance_exec(&code) : record.instance_exec(*args, &code)
|
|
59
57
|
when Array
|
|
60
58
|
if options[:guard]
|
data/lib/aasm/instance_base.rb
CHANGED
|
@@ -10,7 +10,7 @@ module AASM
|
|
|
10
10
|
#
|
|
11
11
|
# Adds
|
|
12
12
|
#
|
|
13
|
-
#
|
|
13
|
+
# after_initialize :aasm_ensure_initial_state
|
|
14
14
|
#
|
|
15
15
|
# As a result, it doesn't matter when you define your methods - the following 2 are equivalent
|
|
16
16
|
#
|
|
@@ -142,9 +142,9 @@ module AASM
|
|
|
142
142
|
|
|
143
143
|
def aasm_raw_attribute_value(state)
|
|
144
144
|
if aasm_enum
|
|
145
|
-
|
|
145
|
+
self.class.send(aasm_enum)[state]
|
|
146
146
|
else
|
|
147
|
-
|
|
147
|
+
state.to_s
|
|
148
148
|
end
|
|
149
149
|
end
|
|
150
150
|
|
|
@@ -166,7 +166,7 @@ module AASM
|
|
|
166
166
|
def aasm_ensure_initial_state
|
|
167
167
|
# checking via respond_to? does not work in Rails <= 3
|
|
168
168
|
# if respond_to?(self.class.aasm.attribute_name) && send(self.class.aasm.attribute_name).blank? # Rails 4
|
|
169
|
-
if
|
|
169
|
+
if attribute_names.include?(self.class.aasm.attribute_name.to_s) && send(self.class.aasm.attribute_name).blank?
|
|
170
170
|
aasm.enter_initial_state
|
|
171
171
|
end
|
|
172
172
|
end
|
|
@@ -37,7 +37,7 @@ module AASM
|
|
|
37
37
|
if new_record?
|
|
38
38
|
state.blank? ? aasm.determine_state_name(self.class.aasm.initial_state) : state.to_sym
|
|
39
39
|
else
|
|
40
|
-
state.
|
|
40
|
+
state.blank? ? nil : state.to_sym
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -71,6 +71,9 @@ module AASM
|
|
|
71
71
|
elsif @klass.ancestors.map {|klass| klass.to_s}.include?("Mongoid::Document")
|
|
72
72
|
scope_options = lambda { @klass.send(:where, {@klass.aasm.attribute_name.to_sym => name.to_s}) }
|
|
73
73
|
@klass.send(:scope, name, scope_options)
|
|
74
|
+
elsif @klass.ancestors.map {|klass| klass.to_s}.include?("MongoMapper::Document")
|
|
75
|
+
conditions = { @klass.aasm.attribute_name.to_sym => name.to_s }
|
|
76
|
+
@klass.scope(name, lambda { @klass.where(conditions) })
|
|
74
77
|
end
|
|
75
78
|
end
|
|
76
79
|
end
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AASM
|
|
4
|
+
module Persistence
|
|
5
|
+
module MongoMapperPersistence
|
|
6
|
+
# This method:
|
|
7
|
+
#
|
|
8
|
+
# * extends the model with ClassMethods
|
|
9
|
+
# * includes InstanceMethods
|
|
10
|
+
#
|
|
11
|
+
# Adds
|
|
12
|
+
#
|
|
13
|
+
# before_validation :aasm_ensure_initial_state, :on => :create
|
|
14
|
+
#
|
|
15
|
+
# As a result, it doesn't matter when you define your methods - the following 2 are equivalent
|
|
16
|
+
#
|
|
17
|
+
# class Foo
|
|
18
|
+
# include MongoMapper::Document
|
|
19
|
+
# def aasm_write_state(state)
|
|
20
|
+
# "bar"
|
|
21
|
+
# end
|
|
22
|
+
# include AASM
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# class Foo < ActiveRecord::Base
|
|
26
|
+
# include MongoMapper::Document
|
|
27
|
+
# include AASM
|
|
28
|
+
# def aasm_write_state(state)
|
|
29
|
+
# "bar"
|
|
30
|
+
# end
|
|
31
|
+
# end
|
|
32
|
+
#
|
|
33
|
+
def self.included(base)
|
|
34
|
+
base.send(:include, AASM::Persistence::Base)
|
|
35
|
+
base.extend AASM::Persistence::MongoMapperPersistence::ClassMethods
|
|
36
|
+
base.send(:include, AASM::Persistence::MongoMapperPersistence::InstanceMethods)
|
|
37
|
+
|
|
38
|
+
base.before_create :aasm_ensure_initial_state
|
|
39
|
+
|
|
40
|
+
# ensure state is in the list of states
|
|
41
|
+
base.validate :aasm_validate_states
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
module ClassMethods
|
|
45
|
+
|
|
46
|
+
def find_in_state(number, state, *args)
|
|
47
|
+
with_state_scope(state).find!(number, *args)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def count_in_state(state, *args)
|
|
51
|
+
with_state_scope(state).count(*args)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def calculate_in_state(state, *args)
|
|
55
|
+
with_state_scope(state).calculate(*args)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
protected
|
|
59
|
+
def with_state_scope(state)
|
|
60
|
+
where(aasm.attribute_name.to_sym => state.to_s)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
module InstanceMethods
|
|
65
|
+
|
|
66
|
+
# Writes <tt>state</tt> to the state column and persists it to the database
|
|
67
|
+
#
|
|
68
|
+
# foo = Foo.find(1)
|
|
69
|
+
# foo.aasm.current_state # => :opened
|
|
70
|
+
# foo.close!
|
|
71
|
+
# foo.aasm.current_state # => :closed
|
|
72
|
+
# Foo.find(1).aasm.current_state # => :closed
|
|
73
|
+
#
|
|
74
|
+
# NOTE: intended to be called from an event
|
|
75
|
+
def aasm_write_state(state)
|
|
76
|
+
old_value = read_attribute(self.class.aasm.attribute_name)
|
|
77
|
+
aasm_write_attribute state
|
|
78
|
+
|
|
79
|
+
success = if aasm_skipping_validations
|
|
80
|
+
value = aasm_raw_attribute_value state
|
|
81
|
+
self.class.where(self.class.primary_key => self.id).update_all(self.class.aasm.attribute_name => value) == 1
|
|
82
|
+
else
|
|
83
|
+
self.save
|
|
84
|
+
end
|
|
85
|
+
unless success
|
|
86
|
+
write_attribute(self.class.aasm.attribute_name, old_value)
|
|
87
|
+
return false
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
true
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Writes <tt>state</tt> to the state column, but does not persist it to the database
|
|
94
|
+
#
|
|
95
|
+
# foo = Foo.find(1)
|
|
96
|
+
# foo.aasm.current_state # => :opened
|
|
97
|
+
# foo.close
|
|
98
|
+
# foo.aasm.current_state # => :closed
|
|
99
|
+
# Foo.find(1).aasm.current_state # => :opened
|
|
100
|
+
# foo.save
|
|
101
|
+
# foo.aasm.current_state # => :closed
|
|
102
|
+
# Foo.find(1).aasm.current_state # => :closed
|
|
103
|
+
#
|
|
104
|
+
# NOTE: intended to be called from an event
|
|
105
|
+
def aasm_write_state_without_persistence(state)
|
|
106
|
+
aasm_write_attribute state
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
def aasm_enum
|
|
111
|
+
case AASM::StateMachine[self.class].config.enum
|
|
112
|
+
when false then nil
|
|
113
|
+
when true then aasm_guess_enum_method
|
|
114
|
+
when nil then aasm_guess_enum_method if aasm_column_looks_like_enum
|
|
115
|
+
else AASM::StateMachine[self.class].config.enum
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def aasm_column_looks_like_enum
|
|
120
|
+
self.class.keys[self.class.aasm.attribute_name.to_s].type == Integer
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def aasm_guess_enum_method
|
|
124
|
+
self.class.aasm.attribute_name.to_s.pluralize.to_sym
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def aasm_skipping_validations
|
|
128
|
+
AASM::StateMachine[self.class].config.skip_validation_on_save
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def aasm_write_attribute(state)
|
|
132
|
+
write_attribute self.class.aasm.attribute_name, aasm_raw_attribute_value(state)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def aasm_raw_attribute_value(state)
|
|
136
|
+
if aasm_enum
|
|
137
|
+
self.class.send(aasm_enum)[state]
|
|
138
|
+
else
|
|
139
|
+
state.to_s
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Ensures that if the aasm_state column is nil and the record is new
|
|
144
|
+
# that the initial state gets populated before validation on create
|
|
145
|
+
#
|
|
146
|
+
# foo = Foo.new
|
|
147
|
+
# foo.aasm_state # => nil
|
|
148
|
+
# foo.valid?
|
|
149
|
+
# foo.aasm_state # => "open" (where :open is the initial state)
|
|
150
|
+
#
|
|
151
|
+
#
|
|
152
|
+
# foo = Foo.find(:first)
|
|
153
|
+
# foo.aasm_state # => 1
|
|
154
|
+
# foo.aasm_state = nil
|
|
155
|
+
# foo.valid?
|
|
156
|
+
# foo.aasm_state # => nil
|
|
157
|
+
#
|
|
158
|
+
def aasm_ensure_initial_state
|
|
159
|
+
return send("#{self.class.aasm.attribute_name}=", aasm.enter_initial_state.to_s) if send(self.class.aasm.attribute_name).blank?
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def aasm_validate_states
|
|
163
|
+
send("#{self.class.aasm.attribute_name}=", aasm.enter_initial_state.to_s) if send(self.class.aasm.attribute_name).blank?
|
|
164
|
+
unless AASM::StateMachine[self.class].config.skip_validation_on_save
|
|
165
|
+
if aasm.current_state && !aasm.states.include?(aasm.current_state)
|
|
166
|
+
self.errors.add(AASM::StateMachine[self.class].config.column , "is invalid")
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end # InstanceMethods
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
end # Persistence
|
|
174
|
+
end # AASM
|
|
@@ -35,11 +35,7 @@ module AASM
|
|
|
35
35
|
base.extend AASM::Persistence::MongoidPersistence::ClassMethods
|
|
36
36
|
base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods)
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
# base.before_validation_on_create :aasm_ensure_initial_state
|
|
40
|
-
base.before_validation :aasm_ensure_initial_state
|
|
41
|
-
# ensure initial aasm state even when validations are skipped
|
|
42
|
-
base.before_create :aasm_ensure_initial_state
|
|
38
|
+
base.after_initialize :aasm_ensure_initial_state
|
|
43
39
|
end
|
|
44
40
|
|
|
45
41
|
module ClassMethods
|
data/lib/aasm/persistence.rb
CHANGED
|
@@ -10,6 +10,8 @@ module AASM
|
|
|
10
10
|
include_persistence base, :active_record
|
|
11
11
|
elsif hierarchy.include?("Mongoid::Document")
|
|
12
12
|
include_persistence base, :mongoid
|
|
13
|
+
elsif hierarchy.include?("MongoMapper::Document")
|
|
14
|
+
include_persistence base, :mongo_mapper
|
|
13
15
|
elsif hierarchy.include?("Sequel::Model")
|
|
14
16
|
include_persistence base, :sequel
|
|
15
17
|
else
|
data/lib/aasm/version.rb
CHANGED
data/spec/database.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
ActiveRecord::Migration.suppress_messages do
|
|
2
|
-
%w{gates readers writers transients simples no_scopes no_direct_assignments thieves localizer_test_models persisted_states provided_and_persisted_states with_enums with_true_enums with_false_enums}.each do |table_name|
|
|
2
|
+
%w{gates readers writers transients simples no_scopes no_direct_assignments thieves localizer_test_models persisted_states provided_and_persisted_states with_enums with_true_enums with_false_enums false_states}.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
|