state_machine-audit_trail 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OWM5NDNmMjY4ZDAyZjkxNzhjNWVmZGMxM2ZlNDNkN2ViZTJmZjY1Zg==
5
+ data.tar.gz: !binary |-
6
+ Y2JlMTdiOWExODEyNTM5ZGY4MzFhMGRjMGY0OTNjZDNhYzQyNjMzZA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ M2U0MzBiN2MxNDc3Y2E3YTczZDg0Mjc4NjkxOWQwNDcwZjlmODU1Yjg5ZmVk
10
+ OTc1YjI0OTc1YzZkMjJhZWZiNzE5Njg2YzdhNjhmM2IzYTIzZjIwMDg3NWYz
11
+ NzljOTk3NWZkZThlODVlZDQyMWMxZjRjZGNmZjg2Zjg2MWU5NWE=
12
+ data.tar.gz: !binary |-
13
+ NzM5ODc4ZGIwNGY5YmE5NzU0YjZiOTNhZTM2MjA2NzQzZmM1ZWUyNWNmMWJl
14
+ ODU1OTU1Yzk3ZjIyN2ZjZGYwMDI2YTdkNDU1Y2U1MjJlYWNjMmNkZDMxMWI0
15
+ MTI3MDdjOTM2YmY1OTNjNzg3MjNkNDViZjBiNTg4NzUyNDhlZjA=
data/README.rdoc CHANGED
@@ -1,4 +1,4 @@
1
- = StateMachine audit trail
1
+ = StateMachine audit trail {<img src="https://travis-ci.org/wvanbergen/state_machine-audit_trail.png" />}[https://travis-ci.org/wvanbergen/state_machine-audit_trail]
2
2
 
3
3
  This plugin for the state machine gem (see https://github.com/pluginaweek/state_machine) adds support for keeping an audit trail for any state machine. Having an audit trail gives you a complete history of the state changes in your model. This history allows you to investigate incidents or perform analytics, like: "How long does it take on average to go from state a to state b?", or "What percentage of cases goes from state a to b via state c?"
4
4
 
@@ -3,9 +3,9 @@ class StateMachine::AuditTrail::Backend::ActiveRecord < StateMachine::AuditTrail
3
3
 
4
4
  def initialize(transition_class, owner_class, context_to_log = nil)
5
5
  self.context_to_log = context_to_log
6
- @association = transition_class.to_s.tableize.to_sym
6
+ @association = transition_class.to_s.tableize.split('/').last.to_sym
7
7
  super transition_class
8
- owner_class.has_many @association
8
+ owner_class.has_many(@association, :class_name => transition_class.to_s) unless owner_class.reflect_on_association(@association)
9
9
  end
10
10
 
11
11
  def log(object, event, from, to, timestamp = Time.now)
@@ -13,6 +13,13 @@ class StateMachine::AuditTrail::Backend::ActiveRecord < StateMachine::AuditTrail
13
13
  # right thing with regards to timezones.
14
14
  params = {:event => event, :from => from, :to => to}
15
15
  params[self.context_to_log] = object.send(self.context_to_log) unless self.context_to_log.nil?
16
- object.send(@association).create(params)
16
+
17
+ if object.new_record?
18
+ object.send(@association).build(params)
19
+ else
20
+ object.send(@association).create(params)
21
+ end
22
+
23
+ nil
17
24
  end
18
25
  end
@@ -12,7 +12,7 @@ class StateMachine::AuditTrail::Backend::Mongoid < StateMachine::AuditTrail::Bac
12
12
  def log(object, event, from, to, timestamp = Time.now)
13
13
  tc = transition_class
14
14
  foreign_key_field = tc.relations.keys.first
15
- transition_class.create(foreign_key_field => object, :event => event, :from => from, :to => to, :create_at => timestamp)
15
+ transition_class.create(foreign_key_field => object, :event => event, :from => from, :to => to, :created_at => timestamp)
16
16
  end
17
17
 
18
18
 
@@ -16,9 +16,11 @@ module StateMachine::AuditTrail::TransitionAuditing
16
16
  state_machine.audit_trail(options[:context_to_log]).log(object, transition.event, transition.from, transition.to)
17
17
  end
18
18
 
19
- state_machine.owner_class.after_create do |object|
20
- if !object.send(state_machine.attribute).nil?
21
- state_machine.audit_trail(options[:context_to_log]).log(object, nil, nil, object.send(state_machine.attribute))
19
+ unless state_machine.action == nil
20
+ state_machine.owner_class.after_create do |object|
21
+ if !object.send(state_machine.attribute).nil?
22
+ state_machine.audit_trail(options[:context_to_log]).log(object, nil, nil, object.send(state_machine.attribute))
23
+ end
22
24
  end
23
25
  end
24
26
  end
@@ -1,5 +1,5 @@
1
1
  module StateMachine
2
2
  module AuditTrail
3
- VERSION = "0.1.5"
3
+ VERSION = "0.1.6"
4
4
  end
5
5
  end
@@ -39,6 +39,10 @@ class ActiveRecordTestModelWithMultipleStateMachinesSecondTransition < ActiveRec
39
39
  belongs_to :test_model
40
40
  end
41
41
 
42
+ class ActiveRecordTestModelWithMultipleStateMachinesThirdTransition < ActiveRecord::Base
43
+ belongs_to :test_model
44
+ end
45
+
42
46
  class ActiveRecordTestModel < ActiveRecord::Base
43
47
 
44
48
  state_machine :state, :initial => :waiting do # log initial state?
@@ -102,8 +106,38 @@ class ActiveRecordTestModelWithMultipleStateMachines < ActiveRecord::Base
102
106
  transition nil => :beginning_second
103
107
  end
104
108
  end
109
+
110
+ state_machine :third, :action => nil do
111
+ store_audit_trail
112
+
113
+ event :begin_third do
114
+ transition nil => :beginning_third
115
+ end
116
+
117
+ event :end_third do
118
+ transition :beginning_third => :done_third
119
+ end
120
+ end
105
121
  end
106
122
 
123
+ module SomeNamespace
124
+ class ActiveRecordTestModel < ActiveRecord::Base
125
+
126
+ state_machine :state, :initial => :waiting do # log initial state?
127
+ store_audit_trail
128
+
129
+ event :start do
130
+ transition [:waiting, :stopped] => :started
131
+ end
132
+
133
+ event :stop do
134
+ transition :started => :stopped
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+
107
141
  def create_transition_table(owner_class, state, add_context = false)
108
142
  class_name = "#{owner_class.name}#{state.to_s.camelize}Transition"
109
143
  ActiveRecord::Base.connection.create_table(class_name.tableize) do |t|
@@ -119,4 +153,5 @@ end
119
153
  create_transition_table(ActiveRecordTestModel, :state)
120
154
  create_transition_table(ActiveRecordTestModelWithContext, :state, true)
121
155
  create_transition_table(ActiveRecordTestModelWithMultipleStateMachines, :first)
122
- create_transition_table(ActiveRecordTestModelWithMultipleStateMachines, :second)
156
+ create_transition_table(ActiveRecordTestModelWithMultipleStateMachines, :second)
157
+ create_transition_table(ActiveRecordTestModelWithMultipleStateMachines, :third)
@@ -13,9 +13,12 @@ describe StateMachine::AuditTrail::Backend::ActiveRecord do
13
13
  ActiveRecordTestModel.reflect_on_association(:active_record_test_model_state_transitions).collection?.should be_true
14
14
  end
15
15
 
16
- context 'on an object with a single state machine' do
17
- let!(:state_machine) { ActiveRecordTestModel.create! }
16
+ it "should handle namespaced models" do
17
+ backend = StateMachine::AuditTrail::Backend.create_for_transition_class(ActiveRecordTestModelStateTransition, SomeNamespace::ActiveRecordTestModel)
18
+ SomeNamespace::ActiveRecordTestModel.reflect_on_association(:active_record_test_model_state_transitions).collection?.should be_true
19
+ end
18
20
 
21
+ shared_examples "a state machine audit trail" do
19
22
  it "should log an event with all fields set correctly" do
20
23
  state_machine.start!
21
24
  last_transition = ActiveRecordTestModelStateTransition.where(:active_record_test_model_id => state_machine.id).last
@@ -27,12 +30,26 @@ describe StateMachine::AuditTrail::Backend::ActiveRecord do
27
30
  last_transition.created_at.should be_within(10.seconds).of(Time.now.utc)
28
31
  end
29
32
 
33
+ it "should do nothing when the transition is not executed successfully" do
34
+ lambda { state_machine.stop }.should_not change(ActiveRecordTestModelStateTransition, :count)
35
+ end
36
+ end
37
+
38
+ context 'on an existing object with a single state machine' do
39
+ let!(:state_machine) { ActiveRecordTestModel.create! }
40
+ include_examples "a state machine audit trail"
41
+
30
42
  it "should log multiple events" do
31
43
  lambda { state_machine.start && state_machine.stop && state_machine.start }.should change(ActiveRecordTestModelStateTransition, :count).by(3)
32
44
  end
45
+ end
33
46
 
34
- it "should do nothing when the transition is not executed successfully" do
35
- lambda { state_machine.stop }.should_not change(ActiveRecordTestModelStateTransition, :count)
47
+ context 'on a new object with a single state machine' do
48
+ let!(:state_machine) { ActiveRecordTestModel.new }
49
+ include_examples "a state machine audit trail"
50
+
51
+ it "should log multiple events including the first event from save" do
52
+ lambda { state_machine.start && state_machine.stop && state_machine.start }.should change(ActiveRecordTestModelStateTransition, :count).by(4)
36
53
  end
37
54
  end
38
55
 
@@ -100,6 +117,23 @@ describe StateMachine::AuditTrail::Backend::ActiveRecord do
100
117
  first_transition.to.should == 'beginning_second'
101
118
  first_transition.created_at.should be_within(10.seconds).of(Time.now.utc)
102
119
  end
120
+
121
+ it "should be fine transitioning before saved on an :action => nil state machine" do
122
+ lambda do
123
+ machine = state_machine_class.new
124
+ machine.begin_third
125
+ machine.save!
126
+ end.should change(ActiveRecordTestModelWithMultipleStateMachinesThirdTransition, :count).by(1)
127
+ end
128
+
129
+ it "should queue up transitions to be saved before being saved on an :action => nil state machine" do
130
+ lambda do
131
+ machine = state_machine_class.new
132
+ machine.begin_third
133
+ machine.end_third
134
+ machine.save!
135
+ end.should change(ActiveRecordTestModelWithMultipleStateMachinesThirdTransition, :count).by(2)
136
+ end
103
137
  end
104
138
 
105
139
  context 'on a class using STI' do
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: state_machine-audit_trail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
5
- prerelease:
4
+ version: 0.1.6
6
5
  platform: ruby
7
6
  authors:
8
7
  - Willem van Bergen
@@ -10,12 +9,11 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-09-09 00:00:00.000000000 Z
12
+ date: 2013-12-10 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: state_machine
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
18
  - - ! '>='
21
19
  - !ruby/object:Gem::Version
@@ -23,7 +21,6 @@ dependencies:
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
25
  - - ! '>='
29
26
  - !ruby/object:Gem::Version
@@ -31,7 +28,6 @@ dependencies:
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: rake
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
32
  - - ! '>='
37
33
  - !ruby/object:Gem::Version
@@ -39,7 +35,6 @@ dependencies:
39
35
  type: :development
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
39
  - - ! '>='
45
40
  - !ruby/object:Gem::Version
@@ -47,7 +42,6 @@ dependencies:
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: rspec
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
46
  - - ~>
53
47
  - !ruby/object:Gem::Version
@@ -55,7 +49,6 @@ dependencies:
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
53
  - - ~>
61
54
  - !ruby/object:Gem::Version
@@ -63,7 +56,6 @@ dependencies:
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: activerecord
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
60
  - - ~>
69
61
  - !ruby/object:Gem::Version
@@ -71,7 +63,6 @@ dependencies:
71
63
  type: :development
72
64
  prerelease: false
73
65
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
66
  requirements:
76
67
  - - ~>
77
68
  - !ruby/object:Gem::Version
@@ -79,7 +70,6 @@ dependencies:
79
70
  - !ruby/object:Gem::Dependency
80
71
  name: sqlite3
81
72
  requirement: !ruby/object:Gem::Requirement
82
- none: false
83
73
  requirements:
84
74
  - - ! '>='
85
75
  - !ruby/object:Gem::Version
@@ -87,7 +77,6 @@ dependencies:
87
77
  type: :development
88
78
  prerelease: false
89
79
  version_requirements: !ruby/object:Gem::Requirement
90
- none: false
91
80
  requirements:
92
81
  - - ! '>='
93
82
  - !ruby/object:Gem::Version
@@ -95,7 +84,6 @@ dependencies:
95
84
  - !ruby/object:Gem::Dependency
96
85
  name: mongoid
97
86
  requirement: !ruby/object:Gem::Requirement
98
- none: false
99
87
  requirements:
100
88
  - - ~>
101
89
  - !ruby/object:Gem::Version
@@ -103,7 +91,6 @@ dependencies:
103
91
  type: :development
104
92
  prerelease: false
105
93
  version_requirements: !ruby/object:Gem::Requirement
106
- none: false
107
94
  requirements:
108
95
  - - ~>
109
96
  - !ruby/object:Gem::Version
@@ -111,7 +98,6 @@ dependencies:
111
98
  - !ruby/object:Gem::Dependency
112
99
  name: bson_ext
113
100
  requirement: !ruby/object:Gem::Requirement
114
- none: false
115
101
  requirements:
116
102
  - - ! '>='
117
103
  - !ruby/object:Gem::Version
@@ -119,7 +105,6 @@ dependencies:
119
105
  type: :development
120
106
  prerelease: false
121
107
  version_requirements: !ruby/object:Gem::Requirement
122
- none: false
123
108
  requirements:
124
109
  - - ! '>='
125
110
  - !ruby/object:Gem::Version
@@ -158,27 +143,26 @@ files:
158
143
  homepage: https://github.com/wvanbergen/state_machine-audit_trail
159
144
  licenses:
160
145
  - MIT
146
+ metadata: {}
161
147
  post_install_message:
162
148
  rdoc_options: []
163
149
  require_paths:
164
150
  - lib
165
151
  required_ruby_version: !ruby/object:Gem::Requirement
166
- none: false
167
152
  requirements:
168
153
  - - ! '>='
169
154
  - !ruby/object:Gem::Version
170
155
  version: '0'
171
156
  required_rubygems_version: !ruby/object:Gem::Requirement
172
- none: false
173
157
  requirements:
174
158
  - - ! '>='
175
159
  - !ruby/object:Gem::Version
176
160
  version: '0'
177
161
  requirements: []
178
162
  rubyforge_project: state_machine
179
- rubygems_version: 1.8.23
163
+ rubygems_version: 2.0.7
180
164
  signing_key:
181
- specification_version: 3
165
+ specification_version: 4
182
166
  summary: Log transitions on a state machine to support auditing and business process
183
167
  analytics.
184
168
  test_files:
@@ -188,3 +172,4 @@ test_files:
188
172
  - spec/state_machine/active_record_spec.rb
189
173
  - spec/state_machine/audit_trail_spec.rb
190
174
  - spec/state_machine/mongoid_spec.rb
175
+ has_rdoc: