audited 4.2.0 → 4.3.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 +11 -9
- data/Appraisals +10 -3
- data/Gemfile +1 -1
- data/README.md +57 -44
- data/Rakefile +3 -18
- data/gemfiles/rails40.gemfile +1 -1
- data/gemfiles/rails41.gemfile +1 -1
- data/gemfiles/rails42.gemfile +1 -1
- data/gemfiles/rails50.gemfile +8 -0
- data/lib/audited/audit.rb +97 -57
- data/lib/audited/auditor.rb +86 -43
- data/lib/audited/rspec_matchers.rb +6 -2
- data/lib/audited/sweeper.rb +10 -19
- data/lib/audited/version.rb +1 -1
- data/lib/audited-rspec.rb +4 -0
- data/lib/audited.rb +15 -2
- data/lib/generators/audited/install_generator.rb +20 -0
- data/lib/generators/audited/migration.rb +15 -0
- data/lib/generators/audited/templates/add_association_to_audits.rb +11 -0
- data/lib/generators/audited/templates/add_comment_to_audits.rb +9 -0
- data/lib/generators/audited/templates/add_remote_address_to_audits.rb +10 -0
- data/lib/generators/audited/templates/add_request_uuid_to_audits.rb +10 -0
- data/lib/generators/audited/templates/install.rb +30 -0
- data/lib/generators/audited/templates/rename_association_to_associated.rb +23 -0
- data/lib/generators/audited/templates/rename_changes_to_audited_changes.rb +9 -0
- data/lib/generators/audited/templates/rename_parent_to_association.rb +11 -0
- data/lib/generators/audited/upgrade_generator.rb +57 -0
- data/spec/audited/audit_spec.rb +199 -0
- data/spec/audited/auditor_spec.rb +607 -0
- data/spec/audited/sweeper_spec.rb +106 -0
- data/spec/audited_spec_helpers.rb +6 -22
- data/spec/rails_app/config/environments/test.rb +7 -4
- data/spec/rails_app/config/initializers/secret_token.rb +1 -1
- data/spec/rails_app/config/routes.rb +1 -4
- data/spec/spec_helper.rb +7 -9
- data/spec/support/active_record/models.rb +23 -13
- data/spec/support/active_record/schema.rb +37 -12
- data/test/db/version_1.rb +4 -4
- data/test/db/version_2.rb +4 -4
- data/test/db/version_3.rb +4 -4
- data/test/db/version_4.rb +4 -4
- data/test/db/version_5.rb +2 -2
- data/test/db/version_6.rb +2 -2
- data/test/install_generator_test.rb +1 -1
- data/test/upgrade_generator_test.rb +10 -10
- metadata +56 -76
- data/lib/audited/active_record/version.rb +0 -5
- data/lib/audited/mongo_mapper/version.rb +0 -5
- data/spec/support/mongo_mapper/connection.rb +0 -4
- data/spec/support/mongo_mapper/models.rb +0 -214
data/lib/audited/auditor.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Audited
|
|
|
9
9
|
# To store an audit comment set model.audit_comment to your comment before
|
|
10
10
|
# a create, update or destroy operation.
|
|
11
11
|
#
|
|
12
|
-
# See <tt>Audited::
|
|
12
|
+
# See <tt>Audited::Auditor::ClassMethods#audited</tt>
|
|
13
13
|
# for configuration options
|
|
14
14
|
module Auditor #:nodoc:
|
|
15
15
|
extend ActiveSupport::Concern
|
|
@@ -28,7 +28,7 @@ module Audited
|
|
|
28
28
|
# You can add to those by passing one or an array of fields to skip.
|
|
29
29
|
#
|
|
30
30
|
# class User < ActiveRecord::Base
|
|
31
|
-
# audited :
|
|
31
|
+
# audited except: :password
|
|
32
32
|
# end
|
|
33
33
|
#
|
|
34
34
|
# * +require_comment+ - Ensures that audit_comment is supplied before
|
|
@@ -36,41 +36,35 @@ module Audited
|
|
|
36
36
|
#
|
|
37
37
|
def audited(options = {})
|
|
38
38
|
# don't allow multiple calls
|
|
39
|
-
return if
|
|
39
|
+
return if included_modules.include?(Audited::Auditor::AuditedInstanceMethods)
|
|
40
40
|
|
|
41
|
-
class_attribute :
|
|
42
|
-
class_attribute :
|
|
43
|
-
class_attribute :audit_associated_with, :instance_writer => false
|
|
41
|
+
class_attribute :audit_associated_with, instance_writer: false
|
|
42
|
+
class_attribute :audited_options, instance_writer: false
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
except = self.column_names - options[:only].flatten.map(&:to_s)
|
|
47
|
-
else
|
|
48
|
-
except = default_ignored_attributes + Audited.ignored_attributes
|
|
49
|
-
except |= Array(options[:except]).collect(&:to_s) if options[:except]
|
|
50
|
-
end
|
|
51
|
-
self.non_audited_columns = except
|
|
44
|
+
self.audited_options = options
|
|
52
45
|
self.audit_associated_with = options[:associated_with]
|
|
53
46
|
|
|
54
47
|
if options[:comment_required]
|
|
55
|
-
validates_presence_of :audit_comment, :
|
|
48
|
+
validates_presence_of :audit_comment, if: :auditing_enabled
|
|
56
49
|
before_destroy :require_comment
|
|
57
50
|
end
|
|
58
51
|
|
|
59
52
|
attr_accessor :audit_comment
|
|
60
53
|
|
|
61
|
-
has_many :audits, :
|
|
62
|
-
|
|
54
|
+
has_many :audits, -> { order(version: :asc) }, as: :auditable, class_name: Audit.name
|
|
55
|
+
Audit.audited_class_names << to_s
|
|
63
56
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
on = Array(options[:on])
|
|
58
|
+
after_create :audit_create if on.empty? || on.include?(:create)
|
|
59
|
+
before_update :audit_update if on.empty? || on.include?(:update)
|
|
60
|
+
before_destroy :audit_destroy if on.empty? || on.include?(:destroy)
|
|
67
61
|
|
|
68
62
|
# Define and set after_audit and around_audit callbacks. This might be useful if you want
|
|
69
63
|
# to notify a party after the audit has been created or if you want to access the newly-created
|
|
70
64
|
# audit.
|
|
71
65
|
define_callbacks :audit
|
|
72
|
-
set_callback :audit, :after, :after_audit, :
|
|
73
|
-
set_callback :audit, :around, :around_audit, :
|
|
66
|
+
set_callback :audit, :after, :after_audit, if: lambda { respond_to?(:after_audit, true) }
|
|
67
|
+
set_callback :audit, :around, :around_audit, if: lambda { respond_to?(:around_audit, true) }
|
|
74
68
|
|
|
75
69
|
attr_accessor :version
|
|
76
70
|
|
|
@@ -81,7 +75,11 @@ module Audited
|
|
|
81
75
|
end
|
|
82
76
|
|
|
83
77
|
def has_associated_audits
|
|
84
|
-
has_many :associated_audits, :
|
|
78
|
+
has_many :associated_audits, as: :associated, class_name: Audit.name
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def default_ignored_attributes
|
|
82
|
+
[primary_key, inheritance_column]
|
|
85
83
|
end
|
|
86
84
|
end
|
|
87
85
|
|
|
@@ -120,13 +118,13 @@ module Audited
|
|
|
120
118
|
|
|
121
119
|
# Get a specific revision specified by the version number, or +:previous+
|
|
122
120
|
def revision(version)
|
|
123
|
-
revision_with
|
|
121
|
+
revision_with Audit.reconstruct_attributes(audits_to(version))
|
|
124
122
|
end
|
|
125
123
|
|
|
126
124
|
# Find the oldest revision recorded prior to the date/time provided.
|
|
127
125
|
def revision_at(date_or_time)
|
|
128
126
|
audits = self.audits.up_until(date_or_time)
|
|
129
|
-
revision_with
|
|
127
|
+
revision_with Audit.reconstruct_attributes(audits) unless audits.empty?
|
|
130
128
|
end
|
|
131
129
|
|
|
132
130
|
# List of attributes that are audited.
|
|
@@ -134,28 +132,36 @@ module Audited
|
|
|
134
132
|
attributes.except(*non_audited_columns)
|
|
135
133
|
end
|
|
136
134
|
|
|
135
|
+
def non_audited_columns
|
|
136
|
+
self.class.non_audited_columns
|
|
137
|
+
end
|
|
138
|
+
|
|
137
139
|
protected
|
|
138
140
|
|
|
141
|
+
def non_audited_columns
|
|
142
|
+
self.class.non_audited_columns
|
|
143
|
+
end
|
|
144
|
+
|
|
139
145
|
def revision_with(attributes)
|
|
140
|
-
|
|
146
|
+
dup.tap do |revision|
|
|
141
147
|
revision.id = id
|
|
142
148
|
revision.send :instance_variable_set, '@attributes', self.attributes if rails_below?('4.2.0')
|
|
143
|
-
revision.send :instance_variable_set, '@new_record',
|
|
144
|
-
revision.send :instance_variable_set, '@persisted', !
|
|
149
|
+
revision.send :instance_variable_set, '@new_record', destroyed?
|
|
150
|
+
revision.send :instance_variable_set, '@persisted', !destroyed?
|
|
145
151
|
revision.send :instance_variable_set, '@readonly', false
|
|
146
152
|
revision.send :instance_variable_set, '@destroyed', false
|
|
147
153
|
revision.send :instance_variable_set, '@_destroyed', false
|
|
148
154
|
revision.send :instance_variable_set, '@marked_for_destruction', false
|
|
149
|
-
|
|
155
|
+
Audit.assign_revision_attributes(revision, attributes)
|
|
150
156
|
|
|
151
157
|
# Remove any association proxies so that they will be recreated
|
|
152
158
|
# and reference the correct object for this revision. The only way
|
|
153
159
|
# to determine if an instance variable is a proxy object is to
|
|
154
160
|
# see if it responds to certain methods, as it forwards almost
|
|
155
161
|
# everything to its target.
|
|
156
|
-
|
|
162
|
+
revision.instance_variables.each do |ivar|
|
|
157
163
|
proxy = revision.instance_variable_get ivar
|
|
158
|
-
if !proxy.nil?
|
|
164
|
+
if !proxy.nil? && proxy.respond_to?(:proxy_respond_to?)
|
|
159
165
|
revision.instance_variable_set ivar, nil
|
|
160
166
|
end
|
|
161
167
|
end
|
|
@@ -169,7 +175,15 @@ module Audited
|
|
|
169
175
|
private
|
|
170
176
|
|
|
171
177
|
def audited_changes
|
|
172
|
-
|
|
178
|
+
collection =
|
|
179
|
+
if audited_options[:only]
|
|
180
|
+
audited_columns = self.class.audited_columns.map(&:name)
|
|
181
|
+
changed_attributes.slice(*audited_columns)
|
|
182
|
+
else
|
|
183
|
+
changed_attributes.except(*non_audited_columns)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
collection.inject({}) do |changes, (attr, old_value)|
|
|
173
187
|
changes[attr] = [old_value, self[attr]]
|
|
174
188
|
changes
|
|
175
189
|
end
|
|
@@ -188,32 +202,33 @@ module Audited
|
|
|
188
202
|
end
|
|
189
203
|
|
|
190
204
|
def audit_create
|
|
191
|
-
write_audit(:
|
|
192
|
-
:
|
|
205
|
+
write_audit(action: 'create', audited_changes: audited_attributes,
|
|
206
|
+
comment: audit_comment)
|
|
193
207
|
end
|
|
194
208
|
|
|
195
209
|
def audit_update
|
|
196
210
|
unless (changes = audited_changes).empty? && audit_comment.blank?
|
|
197
|
-
write_audit(:
|
|
198
|
-
:
|
|
211
|
+
write_audit(action: 'update', audited_changes: changes,
|
|
212
|
+
comment: audit_comment)
|
|
199
213
|
end
|
|
200
214
|
end
|
|
201
215
|
|
|
202
216
|
def audit_destroy
|
|
203
|
-
write_audit(:
|
|
204
|
-
:
|
|
217
|
+
write_audit(action: 'destroy', audited_changes: audited_attributes,
|
|
218
|
+
comment: audit_comment) unless new_record?
|
|
205
219
|
end
|
|
206
220
|
|
|
207
221
|
def write_audit(attrs)
|
|
208
|
-
attrs[:associated] =
|
|
222
|
+
attrs[:associated] = send(audit_associated_with) unless audit_associated_with.nil?
|
|
209
223
|
self.audit_comment = nil
|
|
210
|
-
run_callbacks(:audit) {
|
|
224
|
+
run_callbacks(:audit) { audits.create(attrs) } if auditing_enabled
|
|
211
225
|
end
|
|
212
226
|
|
|
213
227
|
def require_comment
|
|
214
228
|
if auditing_enabled && audit_comment.blank?
|
|
215
229
|
errors.add(:audit_comment, "Comment required before destruction")
|
|
216
|
-
return false
|
|
230
|
+
return false if Rails.version.start_with?('4.')
|
|
231
|
+
throw :abort
|
|
217
232
|
end
|
|
218
233
|
end
|
|
219
234
|
|
|
@@ -224,12 +239,32 @@ module Audited
|
|
|
224
239
|
def empty_callback #:nodoc:
|
|
225
240
|
end
|
|
226
241
|
|
|
242
|
+
def auditing_enabled
|
|
243
|
+
self.class.auditing_enabled
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def auditing_enabled=(val)
|
|
247
|
+
self.class.auditing_enabled = val
|
|
248
|
+
end
|
|
227
249
|
end # InstanceMethods
|
|
228
250
|
|
|
229
251
|
module AuditedClassMethods
|
|
230
252
|
# Returns an array of columns that are audited. See non_audited_columns
|
|
231
253
|
def audited_columns
|
|
232
|
-
|
|
254
|
+
columns.select {|c| !non_audited_columns.include?(c.name) }
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def non_audited_columns
|
|
258
|
+
@non_audited_columns ||= begin
|
|
259
|
+
options = audited_options
|
|
260
|
+
if options[:only]
|
|
261
|
+
except = column_names - Array.wrap(options[:only]).flatten.map(&:to_s)
|
|
262
|
+
else
|
|
263
|
+
except = default_ignored_attributes + Audited.ignored_attributes
|
|
264
|
+
except |= Array(options[:except]).collect(&:to_s) if options[:except]
|
|
265
|
+
end
|
|
266
|
+
except
|
|
267
|
+
end
|
|
233
268
|
end
|
|
234
269
|
|
|
235
270
|
# Executes the block with auditing disabled.
|
|
@@ -258,8 +293,16 @@ module Audited
|
|
|
258
293
|
# made by +user+. This is not model specific, the method is a
|
|
259
294
|
# convenience wrapper around
|
|
260
295
|
# @see Audit#as_user.
|
|
261
|
-
def audit_as(
|
|
262
|
-
|
|
296
|
+
def audit_as(user, &block)
|
|
297
|
+
Audit.as_user(user, &block)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def auditing_enabled
|
|
301
|
+
Audited.store.fetch("#{table_name}_auditing_enabled", true)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def auditing_enabled=(val)
|
|
305
|
+
Audited.store["#{table_name}_auditing_enabled"] = val
|
|
263
306
|
end
|
|
264
307
|
end
|
|
265
308
|
end
|
|
@@ -76,6 +76,8 @@ module Audited
|
|
|
76
76
|
"Did not expect #{@expectation}"
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
+
alias_method :failure_message_when_negated, :negative_failure_message
|
|
80
|
+
|
|
79
81
|
def description
|
|
80
82
|
description = "audited"
|
|
81
83
|
description += " associated with #{@options[:associated_with]}" if @options.key?(:associated_with)
|
|
@@ -149,6 +151,8 @@ module Audited
|
|
|
149
151
|
"Expected #{model_class} to not have associated audits"
|
|
150
152
|
end
|
|
151
153
|
|
|
154
|
+
alias_method :failure_message_when_negated, :negative_failure_message
|
|
155
|
+
|
|
152
156
|
def description
|
|
153
157
|
"has associated audits"
|
|
154
158
|
end
|
|
@@ -164,9 +168,9 @@ module Audited
|
|
|
164
168
|
end
|
|
165
169
|
|
|
166
170
|
def association_exists?
|
|
167
|
-
|
|
171
|
+
!reflection.nil? &&
|
|
168
172
|
reflection.macro == :has_many &&
|
|
169
|
-
reflection.options[:class_name] ==
|
|
173
|
+
reflection.options[:class_name] == Audit.name
|
|
170
174
|
end
|
|
171
175
|
end
|
|
172
176
|
end
|
data/lib/audited/sweeper.rb
CHANGED
|
@@ -3,15 +3,12 @@ require "rails/observers/action_controller/caching"
|
|
|
3
3
|
|
|
4
4
|
module Audited
|
|
5
5
|
class Sweeper < ActionController::Caching::Sweeper
|
|
6
|
-
observe Audited
|
|
6
|
+
observe Audited::Audit
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
def before(controller)
|
|
8
|
+
def around(controller)
|
|
10
9
|
self.controller = controller
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def after(controller)
|
|
10
|
+
yield
|
|
11
|
+
ensure
|
|
15
12
|
self.controller = nil
|
|
16
13
|
end
|
|
17
14
|
|
|
@@ -36,7 +33,7 @@ module Audited
|
|
|
36
33
|
|
|
37
34
|
def define_callback(klass)
|
|
38
35
|
observer = self
|
|
39
|
-
callback_meth = :
|
|
36
|
+
callback_meth = :_notify_audited_sweeper
|
|
40
37
|
klass.send(:define_method, callback_meth) do
|
|
41
38
|
observer.update(:before_create, self)
|
|
42
39
|
end
|
|
@@ -53,17 +50,11 @@ module Audited
|
|
|
53
50
|
end
|
|
54
51
|
end
|
|
55
52
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
# around_filter collision
|
|
60
|
-
sweeper_class = Class.new(Audited::Sweeper) do
|
|
61
|
-
def self.name
|
|
62
|
-
"#{Audited.audit_class}::Sweeper"
|
|
63
|
-
end
|
|
53
|
+
ActiveSupport.on_load(:action_controller) do
|
|
54
|
+
if defined?(ActionController::Base)
|
|
55
|
+
ActionController::Base.around_action Audited::Sweeper.instance
|
|
64
56
|
end
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
around_filter sweeper_class.instance
|
|
57
|
+
if defined?(ActionController::API)
|
|
58
|
+
ActionController::API.around_action Audited::Sweeper.instance
|
|
68
59
|
end
|
|
69
60
|
end
|
data/lib/audited/version.rb
CHANGED
data/lib/audited.rb
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
require 'rails/observers/active_model/active_model'
|
|
2
|
-
|
|
2
|
+
require 'active_record'
|
|
3
3
|
|
|
4
4
|
module Audited
|
|
5
5
|
class << self
|
|
6
|
-
attr_accessor :ignored_attributes, :current_user_method
|
|
6
|
+
attr_accessor :ignored_attributes, :current_user_method
|
|
7
|
+
|
|
8
|
+
# Deprecate audit_class accessors in preperation of their removal
|
|
9
|
+
def audit_class
|
|
10
|
+
Audited::Audit
|
|
11
|
+
end
|
|
12
|
+
deprecate audit_class: "Audited.audit_class is now always Audited::Audit. This method will be removed."
|
|
7
13
|
|
|
8
14
|
def store
|
|
9
15
|
Thread.current[:audited_store] ||= {}
|
|
@@ -14,3 +20,10 @@ module Audited
|
|
|
14
20
|
|
|
15
21
|
@current_user_method = :current_user
|
|
16
22
|
end
|
|
23
|
+
|
|
24
|
+
require 'audited/auditor'
|
|
25
|
+
require 'audited/audit'
|
|
26
|
+
|
|
27
|
+
::ActiveRecord::Base.send :include, Audited::Auditor
|
|
28
|
+
|
|
29
|
+
require 'audited/sweeper'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'rails/generators'
|
|
2
|
+
require 'rails/generators/migration'
|
|
3
|
+
require 'active_record'
|
|
4
|
+
require 'rails/generators/active_record'
|
|
5
|
+
require 'generators/audited/migration'
|
|
6
|
+
|
|
7
|
+
module Audited
|
|
8
|
+
module Generators
|
|
9
|
+
class InstallGenerator < Rails::Generators::Base
|
|
10
|
+
include Rails::Generators::Migration
|
|
11
|
+
extend Audited::Generators::Migration
|
|
12
|
+
|
|
13
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
14
|
+
|
|
15
|
+
def copy_migration
|
|
16
|
+
migration_template 'install.rb', 'db/migrate/install_audited.rb'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Audited
|
|
2
|
+
module Generators
|
|
3
|
+
module Migration
|
|
4
|
+
# Implement the required interface for Rails::Generators::Migration.
|
|
5
|
+
def next_migration_number(dirname) #:nodoc:
|
|
6
|
+
next_migration_number = current_migration_number(dirname) + 1
|
|
7
|
+
if ::ActiveRecord::Base.timestamped_migrations
|
|
8
|
+
[Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
|
|
9
|
+
else
|
|
10
|
+
"%.3d" % next_migration_number
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
add_column :audits, :association_id, :integer
|
|
4
|
+
add_column :audits, :association_type, :string
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.down
|
|
8
|
+
remove_column :audits, :association_type
|
|
9
|
+
remove_column :audits, :association_id
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :audits, :force => true do |t|
|
|
4
|
+
t.column :auditable_id, :integer
|
|
5
|
+
t.column :auditable_type, :string
|
|
6
|
+
t.column :associated_id, :integer
|
|
7
|
+
t.column :associated_type, :string
|
|
8
|
+
t.column :user_id, :integer
|
|
9
|
+
t.column :user_type, :string
|
|
10
|
+
t.column :username, :string
|
|
11
|
+
t.column :action, :string
|
|
12
|
+
t.column :audited_changes, :text
|
|
13
|
+
t.column :version, :integer, :default => 0
|
|
14
|
+
t.column :comment, :string
|
|
15
|
+
t.column :remote_address, :string
|
|
16
|
+
t.column :request_uuid, :string
|
|
17
|
+
t.column :created_at, :datetime
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
add_index :audits, [:auditable_id, :auditable_type], :name => 'auditable_index'
|
|
21
|
+
add_index :audits, [:associated_id, :associated_type], :name => 'associated_index'
|
|
22
|
+
add_index :audits, [:user_id, :user_type], :name => 'user_index'
|
|
23
|
+
add_index :audits, :request_uuid
|
|
24
|
+
add_index :audits, :created_at
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.down
|
|
28
|
+
drop_table :audits
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
if index_exists? :audits, [:association_id, :association_type], :name => 'association_index'
|
|
4
|
+
remove_index :audits, :name => 'association_index'
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
rename_column :audits, :association_id, :associated_id
|
|
8
|
+
rename_column :audits, :association_type, :associated_type
|
|
9
|
+
|
|
10
|
+
add_index :audits, [:associated_id, :associated_type], :name => 'associated_index'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.down
|
|
14
|
+
if index_exists? :audits, [:associated_id, :associated_type], :name => 'associated_index'
|
|
15
|
+
remove_index :audits, :name => 'associated_index'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
rename_column :audits, :associated_type, :association_type
|
|
19
|
+
rename_column :audits, :associated_id, :association_id
|
|
20
|
+
|
|
21
|
+
add_index :audits, [:association_id, :association_type], :name => 'association_index'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
rename_column :audits, :auditable_parent_id, :association_id
|
|
4
|
+
rename_column :audits, :auditable_parent_type, :association_type
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.down
|
|
8
|
+
rename_column :audits, :association_type, :auditable_parent_type
|
|
9
|
+
rename_column :audits, :association_id, :auditable_parent_id
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'rails/generators'
|
|
2
|
+
require 'rails/generators/migration'
|
|
3
|
+
require 'active_record'
|
|
4
|
+
require 'rails/generators/active_record'
|
|
5
|
+
require 'generators/audited/migration'
|
|
6
|
+
|
|
7
|
+
module Audited
|
|
8
|
+
module Generators
|
|
9
|
+
class UpgradeGenerator < Rails::Generators::Base
|
|
10
|
+
include Rails::Generators::Migration
|
|
11
|
+
extend Audited::Generators::Migration
|
|
12
|
+
|
|
13
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
14
|
+
|
|
15
|
+
def copy_templates
|
|
16
|
+
migrations_to_be_applied do |m|
|
|
17
|
+
migration_template "#{m}.rb", "db/migrate/#{m}.rb"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def migrations_to_be_applied
|
|
24
|
+
Audited::Audit.reset_column_information
|
|
25
|
+
columns = Audited::Audit.columns.map(&:name)
|
|
26
|
+
|
|
27
|
+
yield :add_comment_to_audits unless columns.include?('comment')
|
|
28
|
+
|
|
29
|
+
if columns.include?('changes')
|
|
30
|
+
yield :rename_changes_to_audited_changes
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
unless columns.include?('remote_address')
|
|
34
|
+
yield :add_remote_address_to_audits
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
unless columns.include?('request_uuid')
|
|
38
|
+
yield :add_request_uuid_to_audits
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
unless columns.include?('association_id')
|
|
42
|
+
if columns.include?('auditable_parent_id')
|
|
43
|
+
yield :rename_parent_to_association
|
|
44
|
+
else
|
|
45
|
+
unless columns.include?('associated_id')
|
|
46
|
+
yield :add_association_to_audits
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
if columns.include?('association_id')
|
|
52
|
+
yield :rename_association_to_associated
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|