state_machine-audit_trail 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OWM5NDNmMjY4ZDAyZjkxNzhjNWVmZGMxM2ZlNDNkN2ViZTJmZjY1Zg==
4
+ NDliMWUwOGMyMzhhNzgxODQ3YjU0NWNjNDkwNjI5Nzk1NWVkOTc0OA==
5
5
  data.tar.gz: !binary |-
6
- Y2JlMTdiOWExODEyNTM5ZGY4MzFhMGRjMGY0OTNjZDNhYzQyNjMzZA==
7
- !binary "U0hBNTEy":
6
+ YTFiYmZjMjY3YjhhNjJhYzNlMjhlZmQyYWVjZGY0YjZjMGExOTgyZg==
7
+ SHA512:
8
8
  metadata.gz: !binary |-
9
- M2U0MzBiN2MxNDc3Y2E3YTczZDg0Mjc4NjkxOWQwNDcwZjlmODU1Yjg5ZmVk
10
- OTc1YjI0OTc1YzZkMjJhZWZiNzE5Njg2YzdhNjhmM2IzYTIzZjIwMDg3NWYz
11
- NzljOTk3NWZkZThlODVlZDQyMWMxZjRjZGNmZjg2Zjg2MWU5NWE=
9
+ ZjM3MDNlNTFmNWNiNTdmYWU3ZDMwZjc5OTJkZGI4M2Y5MDZmYmNmY2NiMDNj
10
+ MjQ1YWRhYmViYzk2NzZiNTRkZTQxNzNlNmZiOGI4M2NhMWFjMGFmMmQ2NzRm
11
+ NTQyMGVjZTBmNDI2MmNhYjhhYTFjMTVmY2UxZjhjZmI3NTNkMDg=
12
12
  data.tar.gz: !binary |-
13
- NzM5ODc4ZGIwNGY5YmE5NzU0YjZiOTNhZTM2MjA2NzQzZmM1ZWUyNWNmMWJl
14
- ODU1OTU1Yzk3ZjIyN2ZjZGYwMDI2YTdkNDU1Y2U1MjJlYWNjMmNkZDMxMWI0
15
- MTI3MDdjOTM2YmY1OTNjNzg3MjNkNDViZjBiNTg4NzUyNDhlZjA=
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
- params[self.context_to_log] = object.send(self.context_to_log) unless self.context_to_log.nil?
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)
@@ -1,5 +1,5 @@
1
1
  module StateMachine
2
2
  module AuditTrail
3
- VERSION = "0.1.6"
3
+ VERSION = "0.1.7"
4
4
  end
5
5
  end
@@ -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.6
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-10 00:00:00.000000000 Z
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.0.7
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