state_machines-audit_trail 1.0.0 → 2.0.2
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 +5 -5
- data/.gitignore +2 -1
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +30 -4
- data/Appraisals +16 -0
- data/README.md +30 -8
- data/Rakefile +7 -1
- data/gemfiles/rails_5.0.gemfile +9 -0
- data/gemfiles/rails_5.1.gemfile +8 -0
- data/gemfiles/rails_5.2.gemfile +8 -0
- data/gemfiles/rails_6.0.gemfile +8 -0
- data/gemfiles/rails_edge.gemfile +10 -0
- data/lib/state_machines-audit_trail.rb +1 -0
- data/lib/state_machines/audit_trail/backend.rb +29 -8
- data/lib/state_machines/audit_trail/backend/active_record.rb +4 -6
- data/lib/state_machines/audit_trail/transition_auditing.rb +8 -4
- data/lib/state_machines/audit_trail/version.rb +1 -1
- data/lib/state_machines/audit_trail_generator.rb +1 -0
- data/spec/helpers/active_record.rb +88 -25
- data/spec/helpers/mongoid.rb +3 -0
- data/spec/helpers/mongoid.yml +1 -1
- data/spec/lib/state_machines/audit_trail/backend/active_record_spec.rb +83 -20
- data/spec/lib/state_machines/audit_trail/backend/mongoid_spec.rb +98 -98
- data/spec/lib/state_machines/audit_trail_generator_spec.rb +2 -2
- data/state_machines-audit_trail.gemspec +10 -5
- metadata +32 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fa9c1aad624d9dad005c50ab44eb5522908b1790490f6e8b1eacc1b05261a7e3
|
4
|
+
data.tar.gz: 9bcb723941ab88d56534181ad6be0c147de7262ee408c2a5607a77bd146b94e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ffaacbb29036d844d7a25d72da512906bee8d7a646e63b42b68f3f99bfcd7ff572e33177b84cf85ef079cb284dc2667611ce22b40835d524f065fdfb76f7926f
|
7
|
+
data.tar.gz: 15cf000aea32b80c3f0cf675fe9cad34574ce127d4328c3faea9f70b62e7d35550b67ef62ed9209000bf46c84e949ccec27821ba2d90861cfb075c43ae616a76
|
data/.gitignore
CHANGED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
state_machines-audit_trail
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.1
|
data/.travis.yml
CHANGED
@@ -1,17 +1,43 @@
|
|
1
1
|
language: ruby
|
2
|
-
sudo: false
|
3
2
|
cache: bundler
|
4
3
|
|
5
4
|
script: "bundle exec rake"
|
6
5
|
|
7
6
|
services: mongodb
|
8
7
|
rvm:
|
9
|
-
- 2.1
|
10
|
-
- 2.0.0
|
11
8
|
- 2.2
|
9
|
+
- 2.3
|
10
|
+
- 2.4
|
11
|
+
- 2.5
|
12
|
+
- 2.6
|
13
|
+
- 2.7
|
14
|
+
- ruby-head
|
15
|
+
- jruby-head
|
12
16
|
- jruby
|
13
17
|
- rbx-2
|
18
|
+
gemfile:
|
19
|
+
- gemfiles/rails_5.0.gemfile
|
20
|
+
- gemfiles/rails_5.1.gemfile
|
21
|
+
- gemfiles/rails_5.2.gemfile
|
22
|
+
- gemfiles/rails_6.0.gemfile
|
23
|
+
- gemfiles/rails_edge.gemfile
|
14
24
|
matrix:
|
25
|
+
exclude:
|
26
|
+
- rvm: 2.2
|
27
|
+
gemfile: gemfiles/rails_6.0.gemfile
|
28
|
+
- rvm: 2.3
|
29
|
+
gemfile: gemfiles/rails_6.0.gemfile
|
30
|
+
- rvm: 2.4
|
31
|
+
gemfile: gemfiles/rails_6.0.gemfile
|
32
|
+
- rvm: 2.2
|
33
|
+
gemfile: gemfiles/rails_edge.gemfile
|
34
|
+
- rvm: 2.3
|
35
|
+
gemfile: gemfiles/rails_edge.gemfile
|
36
|
+
- rvm: 2.4
|
37
|
+
gemfile: gemfiles/rails_edge.gemfile
|
15
38
|
allow_failures:
|
16
39
|
- rvm: rbx-2
|
17
|
-
- rvm:
|
40
|
+
- rvm: ruby-head
|
41
|
+
- rvm: jruby-head
|
42
|
+
- gemfile: gemfiles/rails_edge.gemfile
|
43
|
+
|
data/Appraisals
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
appraise 'rails_5.0' do
|
2
|
+
gem 'activerecord', '~> 5.0'
|
3
|
+
gem 'activemodel', '~> 5.0'
|
4
|
+
end
|
5
|
+
|
6
|
+
appraise 'rails_5.1' do
|
7
|
+
gem 'activerecord', '~> 5.1'
|
8
|
+
gem 'activemodel', '~> 5.1'
|
9
|
+
end
|
10
|
+
|
11
|
+
appraise 'rails_edge' do
|
12
|
+
gem 'rails', github: 'rails/rails', branch: 'master'
|
13
|
+
gem 'activerecord', github: 'rails/rails', branch: 'master'
|
14
|
+
gem 'activemodel', github: 'rails/rails', branch: 'master'
|
15
|
+
gem 'arel', github: 'rails/arel', branch: 'master'
|
16
|
+
end
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
[](https://travis-ci.org/state-machines/state_machines-audit_trail)
|
2
|
-
[](https://codeclimate.com/github/state-machines/state_machines-audit_trail)
|
3
3
|
|
4
4
|
# state_machines-audit_trail
|
5
5
|
Log transitions on a [state_machines gem](https://github.com/state-machines/state_machines) to support auditing and business process analytics.
|
@@ -12,7 +12,7 @@ for any state machine. Having an audit trail gives you a complete history of the
|
|
12
12
|
to investigate incidents or perform analytics, like: _"How long does it take on average to go from state a to state b?"_,
|
13
13
|
or _"What percentage of cases goes from state a to b via state c?"_
|
14
14
|
|
15
|
-
For more information read [Why developers should be force-fed state machines](
|
15
|
+
For more information read [Why developers should be force-fed state machines](https://engineering.shopify.com/blogs/engineering/17488160-why-developers-should-be-force-fed-state-machines).
|
16
16
|
|
17
17
|
## ORM support
|
18
18
|
|
@@ -56,7 +56,7 @@ will generate the `SubscriptionStateTransition` model and an accompanying migrat
|
|
56
56
|
|
57
57
|
```ruby
|
58
58
|
class Subscription < ActiveRecord::Base
|
59
|
-
|
59
|
+
state_machine :state, initial: :start do
|
60
60
|
audit_trail
|
61
61
|
...
|
62
62
|
```
|
@@ -64,6 +64,10 @@ class Subscription < ActiveRecord::Base
|
|
64
64
|
### That's it!
|
65
65
|
`audit_trail` will register an `after_transition` callback that is used to log all transitions including the initial state if there is one.
|
66
66
|
|
67
|
+
## Upgrading from state_machine-audit_trail
|
68
|
+
|
69
|
+
See the wiki, https://github.com/state-machines/state_machines-audit_trail/wiki/Converting-from-former-state_machine-audit_trail-to-state_machines-audit_trail
|
70
|
+
|
67
71
|
## Configuration options
|
68
72
|
|
69
73
|
### `:initial` - turn off initial state logging
|
@@ -97,7 +101,7 @@ In order to utilize this feature, you need to:
|
|
97
101
|
#### Example 1 - Store a single attribute value
|
98
102
|
Store `Subscription` `field1` in `Transition` field `field1`:
|
99
103
|
```ruby
|
100
|
-
audit_trail
|
104
|
+
audit_trail context: :field1
|
101
105
|
```
|
102
106
|
|
103
107
|
#### Example 2 - Store multiple attribute values
|
@@ -106,7 +110,25 @@ Store `Subscription` `field1` and `field2` in `Transition` fields `field1` and `
|
|
106
110
|
audit_trail context: [:field1, :field2]
|
107
111
|
```
|
108
112
|
|
109
|
-
#### Example 3 - Store
|
113
|
+
#### Example 3 - Store multiple values from a single context object
|
114
|
+
Store `Subscription` `user` in `Transition` fields `user_id` and `user_name`:
|
115
|
+
```ruby
|
116
|
+
class Subscription < ActiveRecord::Base
|
117
|
+
state_machine :state, initial: :start do
|
118
|
+
audit_trail context: :user
|
119
|
+
...
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class SubscriptionStateTransition < ActiveRecord::Base
|
124
|
+
def user=(u)
|
125
|
+
self.user_id = u.id
|
126
|
+
self.user_name = u.name
|
127
|
+
end
|
128
|
+
end
|
129
|
+
```
|
130
|
+
|
131
|
+
#### Example 4 - Store simple method results
|
110
132
|
Store simple method results.
|
111
133
|
|
112
134
|
Sometimes it can be useful to store dynamically computed information, such as those from a `Subscription` method `#plan_time_remaining`
|
@@ -114,7 +136,7 @@ Sometimes it can be useful to store dynamically computed information, such as th
|
|
114
136
|
|
115
137
|
```ruby
|
116
138
|
class Subscription < ActiveRecord::Base
|
117
|
-
|
139
|
+
state_machine :state, initial: :start do
|
118
140
|
audit_trail :context: :plan_time_remaining
|
119
141
|
...
|
120
142
|
|
@@ -123,12 +145,12 @@ class Subscription < ActiveRecord::Base
|
|
123
145
|
...
|
124
146
|
```
|
125
147
|
|
126
|
-
#### Example
|
148
|
+
#### Example 5 - Store advanced method results
|
127
149
|
Store method results that interrogate the transition for information such as `event` arguments:
|
128
150
|
|
129
151
|
```ruby
|
130
152
|
class Subscription < ActiveRecord::Base
|
131
|
-
|
153
|
+
state_machine :state, initial: :start do
|
132
154
|
audit_trail :context: :user_name
|
133
155
|
...
|
134
156
|
|
data/Rakefile
CHANGED
@@ -6,4 +6,10 @@ RSpec::Core::RakeTask.new(:spec) do |task|
|
|
6
6
|
task.rspec_opts = ['--color']
|
7
7
|
end
|
8
8
|
|
9
|
-
|
9
|
+
if ENV['APPRAISAL_INITIALIZED'] || ENV['TRAVIS']
|
10
|
+
task :default => :spec
|
11
|
+
else
|
12
|
+
require 'appraisal'
|
13
|
+
Appraisal::Task.new
|
14
|
+
task :default => :appraisal
|
15
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rails", github: "rails/rails", branch: "master"
|
6
|
+
gem "activerecord", github: "rails/rails", branch: "master"
|
7
|
+
gem "activemodel", github: "rails/rails", branch: "master"
|
8
|
+
gem "arel", github: "rails/arel", branch: "master"
|
9
|
+
|
10
|
+
gemspec path: "../"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class StateMachines::AuditTrail::Backend < Struct.new(:transition_class, :owner_class, :
|
1
|
+
class StateMachines::AuditTrail::Backend < Struct.new(:transition_class, :owner_class, :options)
|
2
2
|
|
3
3
|
autoload :Mongoid, 'state_machines/audit_trail/backend/mongoid'
|
4
4
|
autoload :ActiveRecord, 'state_machines/audit_trail/backend/active_record'
|
@@ -9,10 +9,18 @@ class StateMachines::AuditTrail::Backend < Struct.new(:transition_class, :owner_
|
|
9
9
|
# - transition: state machine transition object that state machine passes to after/before transition callbacks
|
10
10
|
#
|
11
11
|
def log(object, transition)
|
12
|
-
|
13
|
-
|
12
|
+
|
13
|
+
if transition.machine.presence
|
14
|
+
# full transition object
|
15
|
+
namespace = transition.machine.namespace
|
16
|
+
else
|
17
|
+
# initial state open struct
|
18
|
+
namespace = transition.namespace
|
19
|
+
end
|
20
|
+
fields = {namespace: namespace, event: transition.event ? transition.event.to_s : nil, from: transition.from, to: transition.to}
|
21
|
+
[*options[:context]].each { |field|
|
14
22
|
fields[field] = resolve_context(object, field, transition)
|
15
|
-
}
|
23
|
+
}
|
16
24
|
|
17
25
|
# begin
|
18
26
|
persist(object, fields)
|
@@ -30,16 +38,21 @@ class StateMachines::AuditTrail::Backend < Struct.new(:transition_class, :owner_
|
|
30
38
|
# To add a new ORM, implement something similar to lib/state_machines/audit_trail/backend/active_record.rb
|
31
39
|
# and return from here the appropriate object based on which ORM the transition_class is using
|
32
40
|
#
|
33
|
-
def self.create_for(transition_class, owner_class,
|
41
|
+
def self.create_for(transition_class, owner_class, options = {})
|
34
42
|
if Object.const_defined?('ActiveRecord') && transition_class.ancestors.include?(::ActiveRecord::Base)
|
35
|
-
return StateMachines::AuditTrail::Backend::ActiveRecord.new(transition_class, owner_class,
|
43
|
+
return StateMachines::AuditTrail::Backend::ActiveRecord.new(transition_class, owner_class, options)
|
36
44
|
elsif Object.const_defined?('Mongoid') && transition_class.ancestors.include?(::Mongoid::Document)
|
37
|
-
return StateMachines::AuditTrail::Backend::Mongoid.new(transition_class, owner_class,
|
45
|
+
return StateMachines::AuditTrail::Backend::Mongoid.new(transition_class, owner_class, options)
|
38
46
|
else
|
39
47
|
raise 'Not implemented. Only support for ActiveRecord and Mongoid is implemented. Pull requests welcome.'
|
40
48
|
end
|
41
49
|
end
|
42
50
|
|
51
|
+
# Exists in case ORM layer has a different way of answering this question, but works for most.
|
52
|
+
def new_record?(object)
|
53
|
+
object.new_record?
|
54
|
+
end
|
55
|
+
|
43
56
|
protected
|
44
57
|
|
45
58
|
def persist(object, fields)
|
@@ -47,7 +60,15 @@ class StateMachines::AuditTrail::Backend < Struct.new(:transition_class, :owner_
|
|
47
60
|
end
|
48
61
|
|
49
62
|
def resolve_context(object, context, transition)
|
50
|
-
|
63
|
+
# ---------------
|
64
|
+
# TODO: remove this check after we set a minimum version of Rails/ActiveRecord to 5.1+. At that time, the argument will be removed and the arity check will be enough. - rosskevin
|
65
|
+
# Don't send params to Rails 5+ associations because it triggers a ton of deprecation messages.
|
66
|
+
# @see https://github.com/state-machines/state_machines-audit_trail/issues/6
|
67
|
+
# check if activerecord && the context is an association
|
68
|
+
skip_args = object.is_a?(::ActiveRecord::Base) && object.class.reflections.keys.include?(context.to_s)
|
69
|
+
# ---------------
|
70
|
+
|
71
|
+
if object.method(context).arity != 0 && !skip_args
|
51
72
|
object.send(context, transition)
|
52
73
|
else
|
53
74
|
object.send(context)
|
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'state_machines-activerecord'
|
2
2
|
|
3
3
|
class StateMachines::AuditTrail::Backend::ActiveRecord < StateMachines::AuditTrail::Backend
|
4
|
-
|
5
|
-
|
6
|
-
def initialize(transition_class, owner_class, context = nil)
|
4
|
+
def initialize(transition_class, owner_class, options = {})
|
5
|
+
super
|
7
6
|
@association = transition_class.to_s.tableize.split('/').last.to_sym
|
8
|
-
|
9
|
-
|
10
|
-
owner_class.has_many(@association, class_name: transition_class.to_s) unless owner_class.reflect_on_association(@association)
|
7
|
+
assoc_options = {class_name: transition_class.to_s}.merge(options.slice(:as))
|
8
|
+
owner_class.has_many(@association, **assoc_options) unless owner_class.reflect_on_association(@association)
|
11
9
|
end
|
12
10
|
|
13
11
|
def persist(object, fields)
|
@@ -12,6 +12,7 @@ module StateMachines::AuditTrail::TransitionAuditing
|
|
12
12
|
#
|
13
13
|
# options:
|
14
14
|
# - :class - custom state transition class
|
15
|
+
# - :owner_class - the class which is to own the persisted transition objects
|
15
16
|
# - :context - methods to call/store in field of same name in the state transition class
|
16
17
|
# - :initial - if false, won't log null => initial state transition upon instantiation
|
17
18
|
#
|
@@ -21,18 +22,21 @@ module StateMachines::AuditTrail::TransitionAuditing
|
|
21
22
|
raise ":class option[#{options[:class]}] must be a class (not a string)." unless options[:class].is_a? Class
|
22
23
|
end
|
23
24
|
transition_class = options[:class] || default_transition_class
|
25
|
+
owner_class = options[:owner_class] || self.owner_class
|
24
26
|
|
25
27
|
# backend implements #log to store transition information
|
26
|
-
@backend = StateMachines::AuditTrail::Backend.create_for(transition_class,
|
28
|
+
@backend = StateMachines::AuditTrail::Backend.create_for(transition_class, owner_class, options.slice(:context, :as))
|
27
29
|
|
28
30
|
# Initial state logging can be turned off. Very useful for a model with multiple state_machines using a single TransitionState object for logging
|
29
31
|
unless options[:initial] == false
|
30
32
|
unless state_machine.action == nil
|
31
33
|
# Log the initial transition from null => initial (upon object instantiation)
|
32
34
|
state_machine.owner_class.after_initialize do |object|
|
33
|
-
|
34
|
-
|
35
|
-
|
35
|
+
if state_machine.backend.new_record? object
|
36
|
+
current_state = object.send(state_machine.attribute)
|
37
|
+
if !current_state.nil?
|
38
|
+
state_machine.backend.log(object, OpenStruct.new(namespace: state_machine.namespace, to: current_state))
|
39
|
+
end
|
36
40
|
end
|
37
41
|
end
|
38
42
|
end
|
@@ -12,6 +12,7 @@ class StateMachines::AuditTrailGenerator < ::Rails::Generators::Base
|
|
12
12
|
def create_model
|
13
13
|
args = [transition_class_name,
|
14
14
|
"#{source_model.demodulize.tableize.singularize}:references",
|
15
|
+
'namespace:string',
|
15
16
|
'event:string',
|
16
17
|
'from:string',
|
17
18
|
'to:string',
|
@@ -6,6 +6,11 @@ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':me
|
|
6
6
|
class ARModelStateTransition < ActiveRecord::Base
|
7
7
|
belongs_to :ar_model
|
8
8
|
end
|
9
|
+
|
10
|
+
class ARModelWithNamespaceFooStateTransition < ActiveRecord::Base
|
11
|
+
belongs_to :ar_model_with_namespace
|
12
|
+
end
|
13
|
+
|
9
14
|
class ARModelNoInitialStateTransition < ActiveRecord::Base
|
10
15
|
belongs_to :ar_model_no_initial
|
11
16
|
end
|
@@ -32,7 +37,7 @@ end
|
|
32
37
|
|
33
38
|
class ARModel < ActiveRecord::Base
|
34
39
|
|
35
|
-
state_machine :state, initial: :waiting do
|
40
|
+
state_machine :state, initial: :waiting do
|
36
41
|
audit_trail
|
37
42
|
|
38
43
|
event :start do
|
@@ -47,7 +52,7 @@ end
|
|
47
52
|
|
48
53
|
class ARModelNoInitial < ActiveRecord::Base
|
49
54
|
|
50
|
-
state_machine :state, initial: :waiting do
|
55
|
+
state_machine :state, initial: :waiting do
|
51
56
|
audit_trail initial: false
|
52
57
|
|
53
58
|
event :start do
|
@@ -59,9 +64,25 @@ class ARModelNoInitial < ActiveRecord::Base
|
|
59
64
|
end
|
60
65
|
end
|
61
66
|
end
|
67
|
+
|
68
|
+
class ARModelWithNamespace < ActiveRecord::Base
|
69
|
+
|
70
|
+
state_machine :foo_state, initial: :waiting, namespace: :foo do
|
71
|
+
audit_trail
|
72
|
+
|
73
|
+
event :start do
|
74
|
+
transition [:waiting, :stopped] => :started
|
75
|
+
end
|
76
|
+
|
77
|
+
event :stop do
|
78
|
+
transition :started => :stopped
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
62
83
|
#
|
63
84
|
class ARModelWithContext < ActiveRecord::Base
|
64
|
-
state_machine :state, initial: :waiting do
|
85
|
+
state_machine :state, initial: :waiting do
|
65
86
|
audit_trail context: :context
|
66
87
|
|
67
88
|
event :start do
|
@@ -79,7 +100,7 @@ class ARModelWithContext < ActiveRecord::Base
|
|
79
100
|
end
|
80
101
|
|
81
102
|
class ARModelWithMultipleContext < ActiveRecord::Base
|
82
|
-
state_machine :state, initial: :waiting do
|
103
|
+
state_machine :state, initial: :waiting do
|
83
104
|
audit_trail context: [:context, :second_context, :context_with_args]
|
84
105
|
|
85
106
|
event :start do
|
@@ -150,14 +171,46 @@ class ARModelWithMultipleStateMachines < ActiveRecord::Base
|
|
150
171
|
end
|
151
172
|
end
|
152
173
|
|
153
|
-
|
174
|
+
class ARResourceStateTransition < ActiveRecord::Base
|
175
|
+
belongs_to :resource, polymorphic: true
|
176
|
+
end
|
177
|
+
|
178
|
+
class ARFirstModelWithPolymorphicStateTransition < ActiveRecord::Base
|
179
|
+
state_machine :state, :initial => :pending do
|
180
|
+
audit_trail class: ARResourceStateTransition, as: :ar_resource
|
181
|
+
|
182
|
+
event :start do
|
183
|
+
transition :pending => :in_progress
|
184
|
+
end
|
185
|
+
|
186
|
+
event :finish do
|
187
|
+
transition :in_progress => :complete
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
class ARSecondModelWithPolymorphicStateTransition < ActiveRecord::Base
|
193
|
+
state_machine :state, :initial => :pending do
|
194
|
+
audit_trail class: ARResourceStateTransition, as: :ar_resource
|
195
|
+
|
196
|
+
event :start do
|
197
|
+
transition :pending => :in_progress
|
198
|
+
end
|
199
|
+
|
200
|
+
event :finish do
|
201
|
+
transition :in_progress => :complete
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
module SomeModule
|
154
207
|
class ARModelStateTransition < ActiveRecord::Base
|
155
|
-
belongs_to :
|
208
|
+
belongs_to :ar_model
|
156
209
|
end
|
157
210
|
|
158
211
|
class ARModel < ActiveRecord::Base
|
159
212
|
|
160
|
-
state_machine :state, initial: :waiting do
|
213
|
+
state_machine :state, initial: :waiting do
|
161
214
|
audit_trail
|
162
215
|
|
163
216
|
event :start do
|
@@ -174,9 +227,13 @@ end
|
|
174
227
|
#
|
175
228
|
# Generate tables
|
176
229
|
#
|
177
|
-
def create_model_table(owner_class, multiple_state_machines = false)
|
230
|
+
def create_model_table(owner_class, multiple_state_machines = false, state_column = nil)
|
178
231
|
ActiveRecord::Base.connection.create_table(owner_class.name.tableize) do |t|
|
179
|
-
|
232
|
+
if state_column.presence
|
233
|
+
t.string state_column
|
234
|
+
else
|
235
|
+
t.string :state unless multiple_state_machines
|
236
|
+
end
|
180
237
|
t.string :type
|
181
238
|
|
182
239
|
if multiple_state_machines
|
@@ -189,19 +246,21 @@ def create_model_table(owner_class, multiple_state_machines = false)
|
|
189
246
|
end
|
190
247
|
end
|
191
248
|
|
192
|
-
create_model_table(ARModel)
|
193
|
-
create_model_table(ARModelNoInitial)
|
194
|
-
create_model_table(ARModelWithContext)
|
195
|
-
create_model_table(ARModelWithMultipleContext)
|
196
|
-
create_model_table(ARModelWithMultipleStateMachines, true)
|
197
249
|
|
250
|
+
%w(ARModel ARModelNoInitial ARModelWithContext ARModelWithMultipleContext ARFirstModelWithPolymorphicStateTransition ARSecondModelWithPolymorphicStateTransition).each do |name|
|
251
|
+
create_model_table(name.constantize)
|
252
|
+
end
|
253
|
+
|
254
|
+
create_model_table(ARModelWithNamespace, false, :foo_state)
|
255
|
+
create_model_table(ARModelWithMultipleStateMachines, true)
|
198
256
|
|
199
|
-
def create_transition_table(
|
200
|
-
class_name = "#{
|
257
|
+
def create_transition_table(owner_class_name, state, add_context: false, polymorphic: false)
|
258
|
+
class_name = "#{owner_class_name}#{state.to_s.camelize}Transition"
|
201
259
|
ActiveRecord::Base.connection.create_table(class_name.tableize) do |t|
|
202
260
|
|
203
|
-
|
204
|
-
t.integer
|
261
|
+
t.references "#{owner_class_name.demodulize.underscore}", index: false, polymorphic: polymorphic
|
262
|
+
# t.integer owner_class_name.foreign_key
|
263
|
+
t.string :namespace
|
205
264
|
t.string :event
|
206
265
|
t.string :from
|
207
266
|
t.string :to
|
@@ -213,10 +272,14 @@ def create_transition_table(owner_class, state, add_context = false)
|
|
213
272
|
end
|
214
273
|
end
|
215
274
|
|
216
|
-
|
217
|
-
create_transition_table(
|
218
|
-
|
219
|
-
|
220
|
-
create_transition_table(
|
221
|
-
create_transition_table(
|
222
|
-
create_transition_table(
|
275
|
+
%w(ARModel ARModelNoInitial).each do |name|
|
276
|
+
create_transition_table(name, :state)
|
277
|
+
end
|
278
|
+
|
279
|
+
create_transition_table("ARModelWithNamespace", :foo_state, add_context: false)
|
280
|
+
create_transition_table("ARModelWithContext", :state, add_context: true)
|
281
|
+
create_transition_table("ARModelWithMultipleContext", :state, add_context: true)
|
282
|
+
create_transition_table("ARModelWithMultipleStateMachines", :first)
|
283
|
+
create_transition_table("ARModelWithMultipleStateMachines", :second)
|
284
|
+
create_transition_table("ARModelWithMultipleStateMachines", :third)
|
285
|
+
create_transition_table("ARResource", :state, polymorphic: true)
|
data/spec/helpers/mongoid.rb
CHANGED
@@ -9,6 +9,7 @@ class MongoidTestModelStateTransition
|
|
9
9
|
include Mongoid::Timestamps
|
10
10
|
belongs_to :mongoid_test_model
|
11
11
|
|
12
|
+
field :namespace, type: String
|
12
13
|
field :event, type: String
|
13
14
|
field :from, type: String
|
14
15
|
field :to, type: String
|
@@ -19,6 +20,7 @@ class MongoidTestModelWithMultipleStateMachinesFirstTransition
|
|
19
20
|
include Mongoid::Timestamps
|
20
21
|
belongs_to :mongoid_test_model
|
21
22
|
|
23
|
+
field :namespace, type: String
|
22
24
|
field :event, type: String
|
23
25
|
field :from, type: String
|
24
26
|
field :to, type: String
|
@@ -29,6 +31,7 @@ class MongoidTestModelWithMultipleStateMachinesSecondTransition
|
|
29
31
|
include Mongoid::Timestamps
|
30
32
|
belongs_to :mongoid_test_model
|
31
33
|
|
34
|
+
field :namespace, type: String
|
32
35
|
field :event, type: String
|
33
36
|
field :from, type: String
|
34
37
|
field :to, type: String
|
data/spec/helpers/mongoid.yml
CHANGED
@@ -9,20 +9,35 @@ require 'helpers/active_record'
|
|
9
9
|
describe StateMachines::AuditTrail::Backend::ActiveRecord do
|
10
10
|
|
11
11
|
context ':initial option' do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
context 'default' do
|
13
|
+
it 'new object' do
|
14
|
+
target = ARModel.new
|
15
|
+
# initial transition is built but not saved
|
16
|
+
expect(target.new_record?).to be_truthy
|
17
|
+
expect(target.ar_model_state_transitions.count).to eq 0
|
18
|
+
target.save!
|
19
|
+
|
20
|
+
# initial transition is saved and should be present
|
21
|
+
expect(target.new_record?).to be_falsey
|
22
|
+
expect(target.ar_model_state_transitions.count).to eq 1
|
23
|
+
state_transition = target.ar_model_state_transitions.first
|
24
|
+
assert_transition state_transition, nil, nil, 'waiting'
|
25
|
+
end
|
18
26
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
27
|
+
it 'create object' do
|
28
|
+
target = ARModel.create!
|
29
|
+
# initial transition is saved and should be present
|
30
|
+
expect(target.new_record?).to be_falsey
|
31
|
+
expect(target.ar_model_state_transitions.count).to eq 1
|
32
|
+
state_transition = target.ar_model_state_transitions.first
|
33
|
+
assert_transition state_transition, nil, nil, 'waiting'
|
34
|
+
|
35
|
+
# ensure we don't have a second initial state transition logged (issue #4)
|
36
|
+
target = target.reload()
|
37
|
+
expect(target.ar_model_state_transitions.count).to eq 1
|
38
|
+
state_transition = target.ar_model_state_transitions.first
|
39
|
+
assert_transition state_transition, nil, nil, 'waiting'
|
40
|
+
end
|
26
41
|
end
|
27
42
|
|
28
43
|
it 'false skips log' do
|
@@ -38,6 +53,32 @@ describe StateMachines::AuditTrail::Backend::ActiveRecord do
|
|
38
53
|
end
|
39
54
|
end
|
40
55
|
|
56
|
+
context 'namespaced state_machine' do
|
57
|
+
it 'should log namespace' do
|
58
|
+
target = ARModelWithNamespace.create!
|
59
|
+
|
60
|
+
# initial transition is saved and should be present
|
61
|
+
expect(target.new_record?).to be_falsey
|
62
|
+
expect(target.ar_model_with_namespace_foo_state_transitions.count).to eq 1
|
63
|
+
state_transition = target.ar_model_with_namespace_foo_state_transitions.first
|
64
|
+
expect(state_transition.namespace).to eq 'foo'
|
65
|
+
expect(state_transition.from).to be_nil
|
66
|
+
expect(state_transition.to).to eq 'waiting'
|
67
|
+
expect(state_transition.event).to be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should not log namespace' do
|
71
|
+
target = ARModel.create!
|
72
|
+
expect(target.new_record?).to be_falsey
|
73
|
+
expect(target.ar_model_state_transitions.count).to eq 1
|
74
|
+
state_transition = target.ar_model_state_transitions.first
|
75
|
+
expect(state_transition.namespace).to be_nil
|
76
|
+
expect(state_transition.from).to be_nil
|
77
|
+
expect(state_transition.to).to eq 'waiting'
|
78
|
+
expect(state_transition.event).to be_nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
41
82
|
context '#create_for' do
|
42
83
|
it 'should be Backend::ActiveRecord' do
|
43
84
|
backend = StateMachines::AuditTrail::Backend.create_for(ARModelWithContextStateTransition, ARModel)
|
@@ -49,13 +90,13 @@ describe StateMachines::AuditTrail::Backend::ActiveRecord do
|
|
49
90
|
expect(ARModel.reflect_on_association(:ar_model_state_transitions).collection?).to be_truthy
|
50
91
|
end
|
51
92
|
|
52
|
-
it 'should handle
|
53
|
-
StateMachines::AuditTrail::Backend.create_for(ARModelWithContextStateTransition,
|
54
|
-
expect(
|
93
|
+
it 'should handle models within modules' do
|
94
|
+
StateMachines::AuditTrail::Backend.create_for(ARModelWithContextStateTransition, SomeModule::ARModel)
|
95
|
+
expect(SomeModule::ARModel.reflect_on_association(:ar_model_state_transitions).collection?).to be_truthy
|
55
96
|
end
|
56
97
|
|
57
|
-
it 'should handle
|
58
|
-
StateMachines::AuditTrail::Backend.create_for(
|
98
|
+
it 'should handle state transition models within modules' do
|
99
|
+
StateMachines::AuditTrail::Backend.create_for(SomeModule::ARModelStateTransition, ARModel)
|
59
100
|
expect(ARModel.reflect_on_association(:ar_model_state_transitions).collection?).to be_truthy
|
60
101
|
end
|
61
102
|
end
|
@@ -106,7 +147,7 @@ describe StateMachines::AuditTrail::Backend::ActiveRecord do
|
|
106
147
|
|
107
148
|
context 'wants to log a single context' do
|
108
149
|
before(:each) do
|
109
|
-
StateMachines::AuditTrail::Backend.create_for(ARModelWithContextStateTransition, ARModelWithContext, :context)
|
150
|
+
StateMachines::AuditTrail::Backend.create_for(ARModelWithContextStateTransition, ARModelWithContext, context: :context)
|
110
151
|
end
|
111
152
|
|
112
153
|
let!(:target) { ARModelWithContext.create! }
|
@@ -120,7 +161,7 @@ describe StateMachines::AuditTrail::Backend::ActiveRecord do
|
|
120
161
|
|
121
162
|
context 'wants to log multiple context fields' do
|
122
163
|
before(:each) do
|
123
|
-
StateMachines::AuditTrail::Backend.create_for(ARModelWithMultipleContextStateTransition, ARModelWithMultipleContext, [:context, :second_context, :context_with_args])
|
164
|
+
StateMachines::AuditTrail::Backend.create_for(ARModelWithMultipleContextStateTransition, ARModelWithMultipleContext, context: [:context, :second_context, :context_with_args])
|
124
165
|
end
|
125
166
|
|
126
167
|
let!(:target) { ARModelWithMultipleContext.create! }
|
@@ -222,4 +263,26 @@ describe StateMachines::AuditTrail::Backend::ActiveRecord do
|
|
222
263
|
expect { m.complete! }.not_to raise_error
|
223
264
|
end
|
224
265
|
end
|
266
|
+
|
267
|
+
context 'polymorphic' do
|
268
|
+
it 'creates polymorphic state transitions' do
|
269
|
+
m1 = ARFirstModelWithPolymorphicStateTransition.create!
|
270
|
+
m2 = ARSecondModelWithPolymorphicStateTransition.create!
|
271
|
+
m2.start!
|
272
|
+
m2.finish!
|
273
|
+
|
274
|
+
expect(m1.ar_resource_state_transitions.count).to eq(1)
|
275
|
+
expect(m2.ar_resource_state_transitions.count).to eq(3)
|
276
|
+
expect(ARResourceStateTransition.count).to eq(4)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
private
|
281
|
+
|
282
|
+
def assert_transition(state_transition, event, from, to)
|
283
|
+
# expect(state_transition.namespace).to eq namespace
|
284
|
+
expect(state_transition.event).to eq event
|
285
|
+
expect(state_transition.from).to eq from
|
286
|
+
expect(state_transition.to).to eq to
|
287
|
+
end
|
225
288
|
end
|
@@ -1,98 +1,98 @@
|
|
1
|
-
# reset integrations so that something like ActiveRecord is not loaded and conflicting
|
2
|
-
require 'state_machines'
|
3
|
-
StateMachines::Integrations.reset
|
4
|
-
|
5
|
-
require 'spec_helper'
|
6
|
-
require 'state_machines-mongoid'
|
7
|
-
require 'helpers/mongoid'
|
8
|
-
|
9
|
-
describe StateMachines::AuditTrail::Backend::Mongoid do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
1
|
+
# # reset integrations so that something like ActiveRecord is not loaded and conflicting
|
2
|
+
# require 'state_machines'
|
3
|
+
# StateMachines::Integrations.reset
|
4
|
+
#
|
5
|
+
# require 'spec_helper'
|
6
|
+
# require 'state_machines-mongoid'
|
7
|
+
# require 'helpers/mongoid'
|
8
|
+
#
|
9
|
+
# describe StateMachines::AuditTrail::Backend::Mongoid do
|
10
|
+
#
|
11
|
+
# context '#create_for' do
|
12
|
+
# it 'should create a Mongoid backend' do
|
13
|
+
# backend = StateMachines::AuditTrail::Backend.create_for(MongoidTestModelStateTransition, MongoidTestModel)
|
14
|
+
# expect(backend).to be_instance_of(StateMachines::AuditTrail::Backend::Mongoid)
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# context 'single state machine' do
|
19
|
+
# let!(:target) { MongoidTestModel.create! }
|
20
|
+
#
|
21
|
+
# it 'should populate all fields' do
|
22
|
+
# target.start!
|
23
|
+
# last_transition = MongoidTestModelStateTransition.where(:mongoid_test_model_id => target.id).last
|
24
|
+
#
|
25
|
+
# expect(last_transition.event).to eq 'start'
|
26
|
+
# expect(last_transition.from).to eq 'waiting'
|
27
|
+
# expect(last_transition.to).to eq 'started'
|
28
|
+
# expect(last_transition.created_at).to be_within(10.seconds).of(DateTime.now)
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# it 'should log multiple events' do
|
32
|
+
# expect { target.start && target.stop && target.start }.to change(MongoidTestModelStateTransition, :count).by(3)
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# it 'do nothing on failed transition' do
|
36
|
+
# expect { target.stop }.not_to change(MongoidTestModelStateTransition, :count)
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# context 'multiple state machines' do
|
41
|
+
# let!(:target) { MongoidTestModelWithMultipleStateMachines.create! }
|
42
|
+
#
|
43
|
+
# it 'should log a state transition for the affected state machine' do
|
44
|
+
# expect { target.begin_first! }.to change(MongoidTestModelWithMultipleStateMachinesFirstTransition, :count).by(1)
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# it 'should not log a state transition for the unaffected state machine' do
|
48
|
+
# expect { target.begin_first! }.not_to change(MongoidTestModelWithMultipleStateMachinesSecondTransition, :count)
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# context 'on an object with a state machine having an initial state' do
|
53
|
+
# let(:target_class) { MongoidTestModelWithMultipleStateMachines }
|
54
|
+
# let(:state_transition_class) { MongoidTestModelWithMultipleStateMachinesFirstTransition }
|
55
|
+
#
|
56
|
+
# it 'should log a state transition for the inital state' do
|
57
|
+
# expect { target_class.create! }.to change(state_transition_class, :count).by(1)
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# it 'should only set the :to state for the initial transition' do
|
61
|
+
# target_class.create!
|
62
|
+
# initial_transition = state_transition_class.last
|
63
|
+
# expect(initial_transition.event).to be_nil
|
64
|
+
# expect(initial_transition.from).to be_nil
|
65
|
+
# expect(initial_transition.to).to eq 'beginning'
|
66
|
+
# expect(initial_transition.created_at).to be_within(10.seconds).of(DateTime.now)
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# context 'on an object with a state machine not having an initial state' do
|
71
|
+
# let(:target_class) { MongoidTestModelWithMultipleStateMachines }
|
72
|
+
# let(:state_transition_class) { MongoidTestModelWithMultipleStateMachinesSecondTransition }
|
73
|
+
#
|
74
|
+
# it 'should not log a transition when the object is created' do
|
75
|
+
# expect { target_class.create! }.not_to change(state_transition_class, :count)
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# it 'should log a transition for the first event' do
|
79
|
+
# expect { target_class.create.begin_second! }.to change(state_transition_class, :count).by(1)
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# it 'should not set a value for the :from state on the first transition' do
|
83
|
+
# target_class.create.begin_second!
|
84
|
+
# first_transition = state_transition_class.last
|
85
|
+
# expect(first_transition.event).to eq 'begin_second'
|
86
|
+
# expect(first_transition.from).to be_nil
|
87
|
+
# expect(first_transition.to).to eq 'beginning_second'
|
88
|
+
# expect(first_transition.created_at).to be_within(10.seconds).of(DateTime.now)
|
89
|
+
# end
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# context 'on a class using STI' do
|
93
|
+
# it 'should properly grab the class name from STI models' do
|
94
|
+
# m = MongoidTestModelDescendant.create!
|
95
|
+
# expect { m.start! }.not_to raise_error
|
96
|
+
# end
|
97
|
+
# end
|
98
|
+
# end
|
@@ -10,7 +10,7 @@
|
|
10
10
|
# describe StateMachines::AuditTrailGenerator, type: :generator do
|
11
11
|
#
|
12
12
|
# destination File.expand_path('../../../../tmp', __FILE__)
|
13
|
-
# arguments %w(
|
13
|
+
# arguments %w(SomeModule::Subscription state)
|
14
14
|
#
|
15
15
|
# before(:all) do
|
16
16
|
# prepare_destination
|
@@ -36,7 +36,7 @@
|
|
36
36
|
# end
|
37
37
|
# directory 'some_namespace' do
|
38
38
|
# file 'subscription_state_transition.rb' do
|
39
|
-
# contains 'class
|
39
|
+
# contains 'class SomeModule::SubscriptionStateTransition'
|
40
40
|
# end
|
41
41
|
# end
|
42
42
|
# end
|
@@ -22,12 +22,17 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_development_dependency('state_machines-mongoid')
|
23
23
|
s.add_development_dependency('rake')
|
24
24
|
s.add_development_dependency('rspec', '>= 3.0.0')
|
25
|
-
s.add_development_dependency('activerecord', '>=
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
s.add_development_dependency('activerecord', '>= 5.0.0')
|
26
|
+
if(defined?(JRUBY_VERSION))
|
27
|
+
s.add_development_dependency('activerecord-jdbcsqlite3-adapter')
|
28
|
+
else
|
29
|
+
s.add_development_dependency('sqlite3')
|
30
|
+
end
|
31
|
+
s.add_development_dependency('mongoid', '>= 6.0.0.beta')
|
32
|
+
s.add_development_dependency('bson')
|
29
33
|
s.add_development_dependency('generator_spec')
|
30
|
-
s.add_development_dependency('rails', '>=
|
34
|
+
s.add_development_dependency('rails', '>= 5.0.0')
|
35
|
+
s.add_development_dependency('appraisal', '~> 2.2.0')
|
31
36
|
|
32
37
|
s.files = `git ls-files`.split($/).reject { |f| f =~ /^samples\// }
|
33
38
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: state_machines-audit_trail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Ross
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2020-06-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: state_machines
|
@@ -88,14 +88,14 @@ dependencies:
|
|
88
88
|
requirements:
|
89
89
|
- - ">="
|
90
90
|
- !ruby/object:Gem::Version
|
91
|
-
version:
|
91
|
+
version: 5.0.0
|
92
92
|
type: :development
|
93
93
|
prerelease: false
|
94
94
|
version_requirements: !ruby/object:Gem::Requirement
|
95
95
|
requirements:
|
96
96
|
- - ">="
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version:
|
98
|
+
version: 5.0.0
|
99
99
|
- !ruby/object:Gem::Dependency
|
100
100
|
name: sqlite3
|
101
101
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,16 +116,16 @@ dependencies:
|
|
116
116
|
requirements:
|
117
117
|
- - ">="
|
118
118
|
- !ruby/object:Gem::Version
|
119
|
-
version:
|
119
|
+
version: 6.0.0.beta
|
120
120
|
type: :development
|
121
121
|
prerelease: false
|
122
122
|
version_requirements: !ruby/object:Gem::Requirement
|
123
123
|
requirements:
|
124
124
|
- - ">="
|
125
125
|
- !ruby/object:Gem::Version
|
126
|
-
version:
|
126
|
+
version: 6.0.0.beta
|
127
127
|
- !ruby/object:Gem::Dependency
|
128
|
-
name:
|
128
|
+
name: bson
|
129
129
|
requirement: !ruby/object:Gem::Requirement
|
130
130
|
requirements:
|
131
131
|
- - ">="
|
@@ -158,14 +158,28 @@ dependencies:
|
|
158
158
|
requirements:
|
159
159
|
- - ">="
|
160
160
|
- !ruby/object:Gem::Version
|
161
|
-
version:
|
161
|
+
version: 5.0.0
|
162
162
|
type: :development
|
163
163
|
prerelease: false
|
164
164
|
version_requirements: !ruby/object:Gem::Requirement
|
165
165
|
requirements:
|
166
166
|
- - ">="
|
167
167
|
- !ruby/object:Gem::Version
|
168
|
-
version:
|
168
|
+
version: 5.0.0
|
169
|
+
- !ruby/object:Gem::Dependency
|
170
|
+
name: appraisal
|
171
|
+
requirement: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - "~>"
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: 2.2.0
|
176
|
+
type: :development
|
177
|
+
prerelease: false
|
178
|
+
version_requirements: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - "~>"
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: 2.2.0
|
169
183
|
description: Log transitions on a state_machines to support auditing and business
|
170
184
|
process analytics.
|
171
185
|
email:
|
@@ -178,11 +192,19 @@ extra_rdoc_files: []
|
|
178
192
|
files:
|
179
193
|
- ".gitignore"
|
180
194
|
- ".rspec"
|
195
|
+
- ".ruby-gemset"
|
196
|
+
- ".ruby-version"
|
181
197
|
- ".travis.yml"
|
198
|
+
- Appraisals
|
182
199
|
- Gemfile
|
183
200
|
- LICENSE
|
184
201
|
- README.md
|
185
202
|
- Rakefile
|
203
|
+
- gemfiles/rails_5.0.gemfile
|
204
|
+
- gemfiles/rails_5.1.gemfile
|
205
|
+
- gemfiles/rails_5.2.gemfile
|
206
|
+
- gemfiles/rails_6.0.gemfile
|
207
|
+
- gemfiles/rails_edge.gemfile
|
186
208
|
- lib/state_machines-audit_trail.rb
|
187
209
|
- lib/state_machines/audit_trail.rb
|
188
210
|
- lib/state_machines/audit_trail/backend.rb
|
@@ -220,8 +242,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
220
242
|
- !ruby/object:Gem::Version
|
221
243
|
version: '0'
|
222
244
|
requirements: []
|
223
|
-
|
224
|
-
rubygems_version: 2.4.5
|
245
|
+
rubygems_version: 3.0.3
|
225
246
|
signing_key:
|
226
247
|
specification_version: 4
|
227
248
|
summary: Log transitions on a state_machines to support auditing and business process
|