state_machine-audit_trail 0.1.6 → 0.1.7
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 +9 -9
- data/README.rdoc +4 -0
- data/generators/state_machine_audit_trail_generator.rb +48 -0
- data/lib/state_machine/audit_trail.rb +1 -1
- data/lib/state_machine/audit_trail/backend/active_record.rb +2 -2
- data/lib/state_machine/audit_trail/version.rb +1 -1
- data/spec/helpers/active_record.rb +40 -0
- data/spec/state_machine/active_record_spec.rb +20 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NDliMWUwOGMyMzhhNzgxODQ3YjU0NWNjNDkwNjI5Nzk1NWVkOTc0OA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
7
|
-
|
6
|
+
YTFiYmZjMjY3YjhhNjJhYzNlMjhlZmQyYWVjZGY0YjZjMGExOTgyZg==
|
7
|
+
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZjM3MDNlNTFmNWNiNTdmYWU3ZDMwZjc5OTJkZGI4M2Y5MDZmYmNmY2NiMDNj
|
10
|
+
MjQ1YWRhYmViYzk2NzZiNTRkZTQxNzNlNmZiOGI4M2NhMWFjMGFmMmQ2NzRm
|
11
|
+
NTQyMGVjZTBmNDI2MmNhYjhhYTFjMTVmY2UxZjhjZmI3NTNkMDg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MzY2NzM5M2I4ZjBiNTA4NzE5YmFlYWE1MTliOTUyMjc0NTBhNjM4MmI2NDJj
|
14
|
+
YjljN2NhYmEzZjA2NDgzM2NmNWE0MzNiMzgwNjVmMmE2NjJhMDkzNGJhMDcw
|
15
|
+
Y2IxOWJiOTFhMWE2NzFhNWE0MGY4MDU1OTM2Mzg3OTcyMDZkNTI=
|
data/README.rdoc
CHANGED
@@ -21,6 +21,8 @@ Create a model/table that holds the audit trail. The table needs to have a forei
|
|
21
21
|
|
22
22
|
rails generate state_machine:audit_trail <model> <state_attribute>
|
23
23
|
|
24
|
+
(For Rails 2, use rails generate state_machine_audit_trail <model> <state_attribute> [note the underscore instead of the colon])
|
25
|
+
|
24
26
|
For a model called "Model", and a state attribute "state", this will generate the ModelStateTransition model and an accompanying migration.
|
25
27
|
|
26
28
|
Next, tell your state machine you want to store an audit trail:
|
@@ -41,6 +43,8 @@ That's it! The plugin will register an <tt>after_transition</tt> callback that i
|
|
41
43
|
|
42
44
|
If you would like to store additional messages in the audit trail, you can do so with the following:
|
43
45
|
store_audit_trail :context_to_log => :state_message # Will grab the results of the state_message method on the model and store it in a field called state_message on the audit trail model
|
46
|
+
or
|
47
|
+
store_audit_trail :context_to_log => [:field1, :field2] # Will grab the results of the field1 and field2 methods on the model and store them in fields called field1 and field2 on the audit trail model
|
44
48
|
|
45
49
|
== About
|
46
50
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rails_generator'
|
2
|
+
|
3
|
+
class StateMachineAuditTrailGenerator < Rails::Generator::NamedBase
|
4
|
+
def initialize(runtime_args, runtime_options = {})
|
5
|
+
super
|
6
|
+
@source_model, @state_attribute, @transition_model = runtime_args
|
7
|
+
@state_attribute ||= 'state'
|
8
|
+
@transition_model ||= ''
|
9
|
+
end
|
10
|
+
|
11
|
+
def manifest
|
12
|
+
record do |m|
|
13
|
+
attributes = [Rails::Generator::GeneratedAttribute.new(@source_model.tableize.singularize, :references),
|
14
|
+
Rails::Generator::GeneratedAttribute.new(:event, :string),
|
15
|
+
Rails::Generator::GeneratedAttribute.new(:from, :string),
|
16
|
+
Rails::Generator::GeneratedAttribute.new(:to, :string),
|
17
|
+
Rails::Generator::GeneratedAttribute.new(:created_at, :timestamp)]
|
18
|
+
|
19
|
+
#Model file
|
20
|
+
m.directory File.join('app/models', class_path)
|
21
|
+
m.template 'model:model.rb', File.join('app/models', class_path, "#{transition_file_name}.rb"), :assigns => {:class_name => transition_class_name, :attributes => attributes}
|
22
|
+
|
23
|
+
#Migration
|
24
|
+
options[:skip_timestamps] = true
|
25
|
+
migration_file_path = transition_file_name.gsub(/\//, '_')
|
26
|
+
migration_name = transition_class_name
|
27
|
+
if ActiveRecord::Base.pluralize_table_names
|
28
|
+
migration_name = migration_name.pluralize
|
29
|
+
migration_file_path = migration_file_path.pluralize
|
30
|
+
end
|
31
|
+
|
32
|
+
m.migration_template 'model:migration.rb', 'db/migrate', :assigns => {:migration_name => "Create#{migration_name.gsub(/::/, '')}",
|
33
|
+
:table_name => transition_file_name.pluralize,
|
34
|
+
:attributes => attributes},
|
35
|
+
:migration_file_name => "create_#{migration_file_path}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def transition_class_name
|
42
|
+
@transition_model.blank? ? "#{@source_model.camelize}#{@state_attribute.camelize}Transition" : @transition_model
|
43
|
+
end
|
44
|
+
|
45
|
+
def transition_file_name
|
46
|
+
@transition_model.blank? ? "#{@source_model.downcase}_#{@state_attribute}_transition" : @transition_model.tableize.singularize
|
47
|
+
end
|
48
|
+
end
|
@@ -10,6 +10,6 @@ end
|
|
10
10
|
require 'state_machine/audit_trail/version'
|
11
11
|
require 'state_machine/audit_trail/transition_auditing'
|
12
12
|
require 'state_machine/audit_trail/backend'
|
13
|
-
require 'state_machine/audit_trail/railtie' if defined?(::Rails)
|
13
|
+
require 'state_machine/audit_trail/railtie' if defined?(::Rails) && Rails::VERSION::MAJOR >= 3
|
14
14
|
|
15
15
|
StateMachine::AuditTrail.setup
|
@@ -11,8 +11,8 @@ class StateMachine::AuditTrail::Backend::ActiveRecord < StateMachine::AuditTrail
|
|
11
11
|
def log(object, event, from, to, timestamp = Time.now)
|
12
12
|
# Let ActiveRecord manage the timestamp for us so it does the
|
13
13
|
# right thing with regards to timezones.
|
14
|
-
params = {:event => event, :from => from, :to => to}
|
15
|
-
|
14
|
+
params = {:event => event ? event.to_s : nil, :from => from, :to => to}
|
15
|
+
[context_to_log].flatten(1).each { |context| params[context] = object.send(context) } unless self.context_to_log.nil?
|
16
16
|
|
17
17
|
if object.new_record?
|
18
18
|
object.send(@association).build(params)
|
@@ -16,6 +16,12 @@ ActiveRecord::Base.connection.create_table(:active_record_test_model_with_contex
|
|
16
16
|
t.timestamps
|
17
17
|
end
|
18
18
|
|
19
|
+
ActiveRecord::Base.connection.create_table(:active_record_test_model_with_multiple_contexts) do |t|
|
20
|
+
t.string :state
|
21
|
+
t.string :type
|
22
|
+
t.timestamps
|
23
|
+
end
|
24
|
+
|
19
25
|
ActiveRecord::Base.connection.create_table(:active_record_test_model_with_multiple_state_machines) do |t|
|
20
26
|
t.string :first
|
21
27
|
t.string :second
|
@@ -31,6 +37,10 @@ class ActiveRecordTestModelWithContextStateTransition < ActiveRecord::Base
|
|
31
37
|
belongs_to :test_model
|
32
38
|
end
|
33
39
|
|
40
|
+
class ActiveRecordTestModelWithMultipleContextStateTransition < ActiveRecord::Base
|
41
|
+
belongs_to :test_model
|
42
|
+
end
|
43
|
+
|
34
44
|
class ActiveRecordTestModelWithMultipleStateMachinesFirstTransition < ActiveRecord::Base
|
35
45
|
belongs_to :test_model
|
36
46
|
end
|
@@ -76,6 +86,28 @@ class ActiveRecordTestModelWithContext < ActiveRecord::Base
|
|
76
86
|
end
|
77
87
|
end
|
78
88
|
|
89
|
+
class ActiveRecordTestModelWithMultipleContext < ActiveRecord::Base
|
90
|
+
state_machine :state, :initial => :waiting do # log initial state?
|
91
|
+
store_audit_trail :context_to_log => [:context, :second_context]
|
92
|
+
|
93
|
+
event :start do
|
94
|
+
transition [:waiting, :stopped] => :started
|
95
|
+
end
|
96
|
+
|
97
|
+
event :stop do
|
98
|
+
transition :started => :stopped
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def context
|
103
|
+
"Some context"
|
104
|
+
end
|
105
|
+
|
106
|
+
def second_context
|
107
|
+
"Extra context"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
79
111
|
class ActiveRecordTestModelDescendant < ActiveRecordTestModel
|
80
112
|
end
|
81
113
|
|
@@ -137,6 +169,12 @@ module SomeNamespace
|
|
137
169
|
end
|
138
170
|
end
|
139
171
|
|
172
|
+
module SomeNamespace
|
173
|
+
class ActiveRecordTestModelStateTransition < ActiveRecord::Base
|
174
|
+
belongs_to :test_model
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
140
178
|
|
141
179
|
def create_transition_table(owner_class, state, add_context = false)
|
142
180
|
class_name = "#{owner_class.name}#{state.to_s.camelize}Transition"
|
@@ -146,12 +184,14 @@ def create_transition_table(owner_class, state, add_context = false)
|
|
146
184
|
t.string :from
|
147
185
|
t.string :to
|
148
186
|
t.string :context if add_context
|
187
|
+
t.string :second_context if add_context
|
149
188
|
t.datetime :created_at
|
150
189
|
end
|
151
190
|
end
|
152
191
|
|
153
192
|
create_transition_table(ActiveRecordTestModel, :state)
|
154
193
|
create_transition_table(ActiveRecordTestModelWithContext, :state, true)
|
194
|
+
create_transition_table(ActiveRecordTestModelWithMultipleContext, :state, true)
|
155
195
|
create_transition_table(ActiveRecordTestModelWithMultipleStateMachines, :first)
|
156
196
|
create_transition_table(ActiveRecordTestModelWithMultipleStateMachines, :second)
|
157
197
|
create_transition_table(ActiveRecordTestModelWithMultipleStateMachines, :third)
|
@@ -18,6 +18,11 @@ describe StateMachine::AuditTrail::Backend::ActiveRecord do
|
|
18
18
|
SomeNamespace::ActiveRecordTestModel.reflect_on_association(:active_record_test_model_state_transitions).collection?.should be_true
|
19
19
|
end
|
20
20
|
|
21
|
+
it "should handle namespaced state transition model" do
|
22
|
+
backend = StateMachine::AuditTrail::Backend.create_for_transition_class(SomeNamespace::ActiveRecordTestModelStateTransition, ActiveRecordTestModel)
|
23
|
+
ActiveRecordTestModel.reflect_on_association(:active_record_test_model_state_transitions).collection?.should be_true
|
24
|
+
end
|
25
|
+
|
21
26
|
shared_examples "a state machine audit trail" do
|
22
27
|
it "should log an event with all fields set correctly" do
|
23
28
|
state_machine.start!
|
@@ -67,6 +72,21 @@ describe StateMachine::AuditTrail::Backend::ActiveRecord do
|
|
67
72
|
end
|
68
73
|
end
|
69
74
|
|
75
|
+
context 'on an object with a single state machine that wants to log multiple context fields' do
|
76
|
+
before do
|
77
|
+
backend = StateMachine::AuditTrail::Backend.create_for_transition_class(ActiveRecordTestModelWithMultipleContextStateTransition, ActiveRecordTestModelWithMultipleContext, [:context, :second_context])
|
78
|
+
end
|
79
|
+
|
80
|
+
let!(:state_machine) { ActiveRecordTestModelWithMultipleContext.create! }
|
81
|
+
|
82
|
+
it "should log an event with all fields set correctly" do
|
83
|
+
state_machine.start!
|
84
|
+
last_transition = ActiveRecordTestModelWithMultipleContextStateTransition.where(:active_record_test_model_with_multiple_context_id => state_machine.id).last
|
85
|
+
last_transition.context.should == state_machine.context
|
86
|
+
last_transition.second_context.should == state_machine.second_context
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
70
90
|
context 'on an object with multiple state machines' do
|
71
91
|
let!(:state_machine) { ActiveRecordTestModelWithMultipleStateMachines.create! }
|
72
92
|
|
metadata
CHANGED
@@ -1,7 +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.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Willem van Bergen
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-12-
|
12
|
+
date: 2013-12-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: state_machine
|
@@ -124,6 +124,7 @@ files:
|
|
124
124
|
- LICENSE
|
125
125
|
- README.rdoc
|
126
126
|
- Rakefile
|
127
|
+
- generators/state_machine_audit_trail_generator.rb
|
127
128
|
- lib/state_machine-audit_trail.rb
|
128
129
|
- lib/state_machine/audit_trail.rb
|
129
130
|
- lib/state_machine/audit_trail/backend.rb
|
@@ -160,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
161
|
version: '0'
|
161
162
|
requirements: []
|
162
163
|
rubyforge_project: state_machine
|
163
|
-
rubygems_version: 2.
|
164
|
+
rubygems_version: 2.1.4
|
164
165
|
signing_key:
|
165
166
|
specification_version: 4
|
166
167
|
summary: Log transitions on a state machine to support auditing and business process
|