audited 4.6.0 → 4.10.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of audited might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.gitignore +0 -1
- data/.rubocop.yml +25 -0
- data/.travis.yml +35 -21
- data/Appraisals +29 -12
- data/CHANGELOG.md +108 -0
- data/README.md +125 -39
- data/gemfiles/rails42.gemfile +3 -0
- data/gemfiles/rails50.gemfile +3 -0
- data/gemfiles/rails51.gemfile +3 -0
- data/gemfiles/rails52.gemfile +4 -2
- data/gemfiles/rails60.gemfile +10 -0
- data/gemfiles/rails61.gemfile +10 -0
- data/lib/audited.rb +2 -1
- data/lib/audited/audit.rb +31 -25
- data/lib/audited/auditor.rb +199 -39
- data/lib/audited/rspec_matchers.rb +70 -21
- data/lib/audited/version.rb +1 -1
- data/lib/generators/audited/templates/add_version_to_auditable_index.rb +21 -0
- data/lib/generators/audited/templates/install.rb +1 -1
- data/lib/generators/audited/upgrade_generator.rb +4 -0
- data/spec/audited/audit_spec.rb +88 -21
- data/spec/audited/auditor_spec.rb +450 -57
- data/spec/audited/rspec_matchers_spec.rb +69 -0
- data/spec/audited/sweeper_spec.rb +15 -6
- data/spec/audited_spec_helpers.rb +16 -2
- data/spec/rails_app/app/assets/config/manifest.js +1 -0
- data/spec/rails_app/app/controllers/application_controller.rb +2 -0
- data/spec/rails_app/config/application.rb +5 -0
- data/spec/rails_app/config/database.yml +1 -0
- data/spec/spec_helper.rb +4 -1
- data/spec/support/active_record/models.rb +50 -3
- data/spec/support/active_record/schema.rb +4 -2
- data/test/db/version_6.rb +2 -0
- data/test/test_helper.rb +1 -2
- data/test/upgrade_generator_test.rb +10 -0
- metadata +60 -22
- data/gemfiles/rails40.gemfile +0 -9
- data/gemfiles/rails41.gemfile +0 -8
data/gemfiles/rails42.gemfile
CHANGED
data/gemfiles/rails50.gemfile
CHANGED
data/gemfiles/rails51.gemfile
CHANGED
data/gemfiles/rails52.gemfile
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
-
gem "rails", ">= 5.2.0
|
6
|
-
gem "mysql2", "
|
5
|
+
gem "rails", ">= 5.2.0", "< 5.3"
|
6
|
+
gem "mysql2", ">= 0.4.4", "< 0.6.0"
|
7
|
+
gem "pg", ">= 0.18", "< 2.0"
|
8
|
+
gem "sqlite3", "~> 1.3.6"
|
7
9
|
|
8
10
|
gemspec name: "audited", path: "../"
|
data/lib/audited.rb
CHANGED
@@ -2,7 +2,7 @@ require 'active_record'
|
|
2
2
|
|
3
3
|
module Audited
|
4
4
|
class << self
|
5
|
-
attr_accessor :ignored_attributes, :current_user_method
|
5
|
+
attr_accessor :ignored_attributes, :current_user_method, :max_audits, :auditing_enabled
|
6
6
|
attr_writer :audit_class
|
7
7
|
|
8
8
|
def audit_class
|
@@ -21,6 +21,7 @@ module Audited
|
|
21
21
|
@ignored_attributes = %w(lock_version created_at updated_at created_on updated_on)
|
22
22
|
|
23
23
|
@current_user_method = :current_user
|
24
|
+
@auditing_enabled = true
|
24
25
|
end
|
25
26
|
|
26
27
|
require 'audited/auditor'
|
data/lib/audited/audit.rb
CHANGED
@@ -16,7 +16,7 @@ module Audited
|
|
16
16
|
class YAMLIfTextColumnType
|
17
17
|
class << self
|
18
18
|
def load(obj)
|
19
|
-
if
|
19
|
+
if text_column?
|
20
20
|
ActiveRecord::Coders::YAMLColumn.new(Object).load(obj)
|
21
21
|
else
|
22
22
|
obj
|
@@ -24,12 +24,16 @@ module Audited
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def dump(obj)
|
27
|
-
if
|
27
|
+
if text_column?
|
28
28
|
ActiveRecord::Coders::YAMLColumn.new(Object).dump(obj)
|
29
29
|
else
|
30
30
|
obj
|
31
31
|
end
|
32
32
|
end
|
33
|
+
|
34
|
+
def text_column?
|
35
|
+
Audited.audit_class.columns_hash["audited_changes"].type.to_s == "text"
|
36
|
+
end
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
@@ -65,7 +69,7 @@ module Audited
|
|
65
69
|
def revision
|
66
70
|
clazz = auditable_type.constantize
|
67
71
|
(clazz.find_by_id(auditable_id) || clazz.new).tap do |m|
|
68
|
-
self.class.assign_revision_attributes(m, self.class.reconstruct_attributes(ancestors).merge(
|
72
|
+
self.class.assign_revision_attributes(m, self.class.reconstruct_attributes(ancestors).merge(audit_version: version))
|
69
73
|
end
|
70
74
|
end
|
71
75
|
|
@@ -88,20 +92,18 @@ module Audited
|
|
88
92
|
|
89
93
|
# Allows user to undo changes
|
90
94
|
def undo
|
91
|
-
|
92
|
-
|
95
|
+
case action
|
96
|
+
when 'create'
|
93
97
|
# destroys a newly created record
|
94
|
-
|
95
|
-
|
98
|
+
auditable.destroy!
|
99
|
+
when 'destroy'
|
96
100
|
# creates a new record with the destroyed record attributes
|
97
|
-
|
98
|
-
|
101
|
+
auditable_type.constantize.create!(audited_changes)
|
102
|
+
when 'update'
|
99
103
|
# changes back attributes
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
104
|
-
audited_object.save
|
104
|
+
auditable.update!(audited_changes.transform_values(&:first))
|
105
|
+
else
|
106
|
+
raise StandardError, "invalid action given #{action}"
|
105
107
|
end
|
106
108
|
end
|
107
109
|
|
@@ -132,21 +134,20 @@ module Audited
|
|
132
134
|
# All audits made during the block called will be recorded as made
|
133
135
|
# by +user+. This method is hopefully threadsafe, making it ideal
|
134
136
|
# for background operations that require audit information.
|
135
|
-
def self.as_user(user
|
137
|
+
def self.as_user(user)
|
138
|
+
last_audited_user = ::Audited.store[:audited_user]
|
136
139
|
::Audited.store[:audited_user] = user
|
137
140
|
yield
|
138
141
|
ensure
|
139
|
-
::Audited.store[:audited_user] =
|
142
|
+
::Audited.store[:audited_user] = last_audited_user
|
140
143
|
end
|
141
144
|
|
142
145
|
# @private
|
143
146
|
def self.reconstruct_attributes(audits)
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
end
|
149
|
-
block_given? ? result : attributes
|
147
|
+
audits.each_with_object({}) do |audit, all|
|
148
|
+
all.merge!(audit.new_attributes)
|
149
|
+
all[:audit_version] = audit.version
|
150
|
+
end
|
150
151
|
end
|
151
152
|
|
152
153
|
# @private
|
@@ -164,15 +165,20 @@ module Audited
|
|
164
165
|
end
|
165
166
|
|
166
167
|
# use created_at as timestamp cache key
|
167
|
-
def self.collection_cache_key(collection = all,
|
168
|
+
def self.collection_cache_key(collection = all, *)
|
168
169
|
super(collection, :created_at)
|
169
170
|
end
|
170
171
|
|
171
172
|
private
|
172
173
|
|
173
174
|
def set_version_number
|
174
|
-
|
175
|
-
|
175
|
+
if action == 'create'
|
176
|
+
self.version = 1
|
177
|
+
else
|
178
|
+
collection = Rails::VERSION::MAJOR == 6 ? self.class.unscoped : self.class
|
179
|
+
max = collection.auditable_finder(auditable_id, auditable_type).maximum(:version) || 0
|
180
|
+
self.version = max + 1
|
181
|
+
end
|
176
182
|
end
|
177
183
|
|
178
184
|
def set_audit_user
|
data/lib/audited/auditor.rb
CHANGED
@@ -33,6 +33,28 @@ module Audited
|
|
33
33
|
#
|
34
34
|
# * +require_comment+ - Ensures that audit_comment is supplied before
|
35
35
|
# any create, update or destroy operation.
|
36
|
+
# * +max_audits+ - Limits the number of stored audits.
|
37
|
+
|
38
|
+
# * +redacted+ - Changes to these fields will be logged, but the values
|
39
|
+
# will not. This is useful, for example, if you wish to audit when a
|
40
|
+
# password is changed, without saving the actual password in the log.
|
41
|
+
# To store values as something other than '[REDACTED]', pass an argument
|
42
|
+
# to the redaction_value option.
|
43
|
+
#
|
44
|
+
# class User < ActiveRecord::Base
|
45
|
+
# audited redacted: :password, redaction_value: SecureRandom.uuid
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# * +if+ - Only audit the model when the given function returns true
|
49
|
+
# * +unless+ - Only audit the model when the given function returns false
|
50
|
+
#
|
51
|
+
# class User < ActiveRecord::Base
|
52
|
+
# audited :if => :active?
|
53
|
+
#
|
54
|
+
# def active?
|
55
|
+
# self.status == 'active'
|
56
|
+
# end
|
57
|
+
# end
|
36
58
|
#
|
37
59
|
def audited(options = {})
|
38
60
|
# don't allow multiple calls
|
@@ -41,9 +63,9 @@ module Audited
|
|
41
63
|
extend Audited::Auditor::AuditedClassMethods
|
42
64
|
include Audited::Auditor::AuditedInstanceMethods
|
43
65
|
|
44
|
-
class_attribute :audit_associated_with,
|
66
|
+
class_attribute :audit_associated_with, instance_writer: false
|
45
67
|
class_attribute :audited_options, instance_writer: false
|
46
|
-
attr_accessor :
|
68
|
+
attr_accessor :audit_version, :audit_comment
|
47
69
|
|
48
70
|
self.audited_options = options
|
49
71
|
normalize_audited_options
|
@@ -51,11 +73,11 @@ module Audited
|
|
51
73
|
self.audit_associated_with = audited_options[:associated_with]
|
52
74
|
|
53
75
|
if audited_options[:comment_required]
|
54
|
-
|
55
|
-
before_destroy :require_comment
|
76
|
+
validate :presence_of_audit_comment
|
77
|
+
before_destroy :require_comment if audited_options[:on].include?(:destroy)
|
56
78
|
end
|
57
79
|
|
58
|
-
has_many :audits, -> { order(version: :asc) }, as: :auditable, class_name: Audited.audit_class.name
|
80
|
+
has_many :audits, -> { order(version: :asc) }, as: :auditable, class_name: Audited.audit_class.name, inverse_of: :auditable
|
59
81
|
Audited.audit_class.audited_class_names << to_s
|
60
82
|
|
61
83
|
after_create :audit_create if audited_options[:on].include?(:create)
|
@@ -78,6 +100,8 @@ module Audited
|
|
78
100
|
end
|
79
101
|
|
80
102
|
module AuditedInstanceMethods
|
103
|
+
REDACTED = '[REDACTED]'
|
104
|
+
|
81
105
|
# Temporarily turns off auditing while saving.
|
82
106
|
def save_without_auditing
|
83
107
|
without_auditing { save }
|
@@ -93,6 +117,21 @@ module Audited
|
|
93
117
|
self.class.without_auditing(&block)
|
94
118
|
end
|
95
119
|
|
120
|
+
# Temporarily turns on auditing while saving.
|
121
|
+
def save_with_auditing
|
122
|
+
with_auditing { save }
|
123
|
+
end
|
124
|
+
|
125
|
+
# Executes the block with the auditing callbacks enabled.
|
126
|
+
#
|
127
|
+
# @foo.with_auditing do
|
128
|
+
# @foo.save
|
129
|
+
# end
|
130
|
+
#
|
131
|
+
def with_auditing(&block)
|
132
|
+
self.class.with_auditing(&block)
|
133
|
+
end
|
134
|
+
|
96
135
|
# Gets an array of the revisions available
|
97
136
|
#
|
98
137
|
# user.revisions.each do |revision|
|
@@ -101,9 +140,17 @@ module Audited
|
|
101
140
|
# end
|
102
141
|
#
|
103
142
|
def revisions(from_version = 1)
|
104
|
-
|
105
|
-
|
106
|
-
audits.
|
143
|
+
return [] unless audits.from_version(from_version).exists?
|
144
|
+
|
145
|
+
all_audits = audits.select([:audited_changes, :version]).to_a
|
146
|
+
targeted_audits = all_audits.select { |audit| audit.version >= from_version }
|
147
|
+
|
148
|
+
previous_attributes = reconstruct_attributes(all_audits - targeted_audits)
|
149
|
+
|
150
|
+
targeted_audits.map do |audit|
|
151
|
+
previous_attributes.merge!(audit.new_attributes)
|
152
|
+
revision_with(previous_attributes.merge!(version: audit.version))
|
153
|
+
end
|
107
154
|
end
|
108
155
|
|
109
156
|
# Get a specific revision specified by the version number, or +:previous+
|
@@ -122,23 +169,35 @@ module Audited
|
|
122
169
|
|
123
170
|
# List of attributes that are audited.
|
124
171
|
def audited_attributes
|
125
|
-
attributes.except(*non_audited_columns)
|
172
|
+
audited_attributes = attributes.except(*self.class.non_audited_columns)
|
173
|
+
normalize_enum_changes(audited_attributes)
|
126
174
|
end
|
127
175
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
176
|
+
# Returns a list combined of record audits and associated audits.
|
177
|
+
def own_and_associated_audits
|
178
|
+
Audited.audit_class.unscoped
|
179
|
+
.where('(auditable_type = :type AND auditable_id = :id) OR (associated_type = :type AND associated_id = :id)',
|
180
|
+
type: self.class.name, id: id)
|
181
|
+
.order(created_at: :desc)
|
132
182
|
end
|
133
183
|
|
134
|
-
|
135
|
-
|
184
|
+
# Combine multiple audits into one.
|
185
|
+
def combine_audits(audits_to_combine)
|
186
|
+
combine_target = audits_to_combine.last
|
187
|
+
combine_target.audited_changes = audits_to_combine.pluck(:audited_changes).reduce(&:merge)
|
188
|
+
combine_target.comment = "#{combine_target.comment}\nThis audit is the result of multiple audits being combined."
|
189
|
+
|
190
|
+
transaction do
|
191
|
+
combine_target.save!
|
192
|
+
audits_to_combine.unscope(:limit).where("version < ?", combine_target.version).delete_all
|
193
|
+
end
|
136
194
|
end
|
137
195
|
|
196
|
+
protected
|
197
|
+
|
138
198
|
def revision_with(attributes)
|
139
199
|
dup.tap do |revision|
|
140
200
|
revision.id = id
|
141
|
-
revision.send :instance_variable_set, '@attributes', self.attributes if rails_below?('4.2.0')
|
142
201
|
revision.send :instance_variable_set, '@new_record', destroyed?
|
143
202
|
revision.send :instance_variable_set, '@persisted', !destroyed?
|
144
203
|
revision.send :instance_variable_set, '@readonly', false
|
@@ -161,25 +220,62 @@ module Audited
|
|
161
220
|
end
|
162
221
|
end
|
163
222
|
|
164
|
-
def rails_below?(rails_version)
|
165
|
-
Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new(rails_version)
|
166
|
-
end
|
167
|
-
|
168
223
|
private
|
169
224
|
|
170
225
|
def audited_changes
|
171
226
|
all_changes = respond_to?(:changes_to_save) ? changes_to_save : changes
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
227
|
+
filtered_changes = \
|
228
|
+
if audited_options[:only].present?
|
229
|
+
all_changes.slice(*self.class.audited_columns)
|
230
|
+
else
|
231
|
+
all_changes.except(*self.class.non_audited_columns)
|
232
|
+
end
|
233
|
+
|
234
|
+
filtered_changes = redact_values(filtered_changes)
|
235
|
+
filtered_changes = normalize_enum_changes(filtered_changes)
|
236
|
+
filtered_changes.to_hash
|
237
|
+
end
|
238
|
+
|
239
|
+
def normalize_enum_changes(changes)
|
240
|
+
self.class.defined_enums.each do |name, values|
|
241
|
+
if changes.has_key?(name)
|
242
|
+
changes[name] = \
|
243
|
+
if changes[name].is_a?(Array)
|
244
|
+
changes[name].map { |v| values[v] }
|
245
|
+
elsif rails_below?('5.0')
|
246
|
+
changes[name]
|
247
|
+
else
|
248
|
+
values[changes[name]]
|
249
|
+
end
|
250
|
+
end
|
176
251
|
end
|
252
|
+
changes
|
253
|
+
end
|
254
|
+
|
255
|
+
def redact_values(filtered_changes)
|
256
|
+
[audited_options[:redacted]].flatten.compact.each do |option|
|
257
|
+
changes = filtered_changes[option.to_s]
|
258
|
+
new_value = audited_options[:redaction_value] || REDACTED
|
259
|
+
if changes.is_a? Array
|
260
|
+
values = changes.map { new_value }
|
261
|
+
else
|
262
|
+
values = new_value
|
263
|
+
end
|
264
|
+
hash = Hash[option.to_s, values]
|
265
|
+
filtered_changes.merge!(hash)
|
266
|
+
end
|
267
|
+
|
268
|
+
filtered_changes
|
269
|
+
end
|
270
|
+
|
271
|
+
def rails_below?(rails_version)
|
272
|
+
Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new(rails_version)
|
177
273
|
end
|
178
274
|
|
179
275
|
def audits_to(version = nil)
|
180
276
|
if version == :previous
|
181
|
-
version = if self.
|
182
|
-
self.
|
277
|
+
version = if self.audit_version
|
278
|
+
self.audit_version - 1
|
183
279
|
else
|
184
280
|
previous = audits.descending.offset(1).first
|
185
281
|
previous ? previous.version : 1
|
@@ -194,7 +290,7 @@ module Audited
|
|
194
290
|
end
|
195
291
|
|
196
292
|
def audit_update
|
197
|
-
unless (changes = audited_changes).empty? && audit_comment.blank?
|
293
|
+
unless (changes = audited_changes).empty? && (audit_comment.blank? || audited_options[:update_with_comment_only] == false)
|
198
294
|
write_audit(action: 'update', audited_changes: changes,
|
199
295
|
comment: audit_comment)
|
200
296
|
end
|
@@ -208,14 +304,41 @@ module Audited
|
|
208
304
|
def write_audit(attrs)
|
209
305
|
attrs[:associated] = send(audit_associated_with) unless audit_associated_with.nil?
|
210
306
|
self.audit_comment = nil
|
211
|
-
|
307
|
+
|
308
|
+
if auditing_enabled
|
309
|
+
run_callbacks(:audit) {
|
310
|
+
audit = audits.create(attrs)
|
311
|
+
combine_audits_if_needed if attrs[:action] != 'create'
|
312
|
+
audit
|
313
|
+
}
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def presence_of_audit_comment
|
318
|
+
if comment_required_state?
|
319
|
+
errors.add(:audit_comment, "Comment can't be blank!") unless audit_comment.present?
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
def comment_required_state?
|
324
|
+
auditing_enabled &&
|
325
|
+
((audited_options[:on].include?(:create) && self.new_record?) ||
|
326
|
+
(audited_options[:on].include?(:update) && self.persisted? && self.changed?))
|
327
|
+
end
|
328
|
+
|
329
|
+
def combine_audits_if_needed
|
330
|
+
max_audits = audited_options[:max_audits]
|
331
|
+
if max_audits && (extra_count = audits.count - max_audits) > 0
|
332
|
+
audits_to_combine = audits.limit(extra_count + 1)
|
333
|
+
combine_audits(audits_to_combine)
|
334
|
+
end
|
212
335
|
end
|
213
336
|
|
214
337
|
def require_comment
|
215
338
|
if auditing_enabled && audit_comment.blank?
|
216
|
-
errors.add(:audit_comment, "Comment
|
339
|
+
errors.add(:audit_comment, "Comment can't be blank!")
|
217
340
|
return false if Rails.version.start_with?('4.')
|
218
|
-
throw
|
341
|
+
throw(:abort)
|
219
342
|
end
|
220
343
|
end
|
221
344
|
|
@@ -224,11 +347,23 @@ module Audited
|
|
224
347
|
end
|
225
348
|
|
226
349
|
def auditing_enabled
|
227
|
-
|
350
|
+
return run_conditional_check(audited_options[:if]) &&
|
351
|
+
run_conditional_check(audited_options[:unless], matching: false) &&
|
352
|
+
self.class.auditing_enabled
|
228
353
|
end
|
229
354
|
|
230
|
-
def
|
231
|
-
|
355
|
+
def run_conditional_check(condition, matching: true)
|
356
|
+
return true if condition.blank?
|
357
|
+
return condition.call(self) == matching if condition.respond_to?(:call)
|
358
|
+
return send(condition) == matching if respond_to?(condition.to_sym, true)
|
359
|
+
|
360
|
+
true
|
361
|
+
end
|
362
|
+
|
363
|
+
def reconstruct_attributes(audits)
|
364
|
+
attributes = {}
|
365
|
+
audits.each { |audit| attributes.merge!(audit.new_attributes) }
|
366
|
+
attributes
|
232
367
|
end
|
233
368
|
end # InstanceMethods
|
234
369
|
|
@@ -240,9 +375,7 @@ module Audited
|
|
240
375
|
|
241
376
|
# We have to calculate this here since column_names may not be available when `audited` is called
|
242
377
|
def non_audited_columns
|
243
|
-
@non_audited_columns ||=
|
244
|
-
column_names - audited_options[:only] :
|
245
|
-
default_ignored_attributes | audited_options[:except]
|
378
|
+
@non_audited_columns ||= calculate_non_audited_columns
|
246
379
|
end
|
247
380
|
|
248
381
|
def non_audited_columns=(columns)
|
@@ -264,6 +397,20 @@ module Audited
|
|
264
397
|
enable_auditing if auditing_was_enabled
|
265
398
|
end
|
266
399
|
|
400
|
+
# Executes the block with auditing enabled.
|
401
|
+
#
|
402
|
+
# Foo.with_auditing do
|
403
|
+
# @foo.save
|
404
|
+
# end
|
405
|
+
#
|
406
|
+
def with_auditing
|
407
|
+
auditing_was_enabled = auditing_enabled
|
408
|
+
enable_auditing
|
409
|
+
yield
|
410
|
+
ensure
|
411
|
+
disable_auditing unless auditing_was_enabled
|
412
|
+
end
|
413
|
+
|
267
414
|
def disable_auditing
|
268
415
|
self.auditing_enabled = false
|
269
416
|
end
|
@@ -281,23 +428,36 @@ module Audited
|
|
281
428
|
end
|
282
429
|
|
283
430
|
def auditing_enabled
|
284
|
-
Audited.store.fetch("#{table_name}_auditing_enabled", true)
|
431
|
+
Audited.store.fetch("#{table_name}_auditing_enabled", true) && Audited.auditing_enabled
|
285
432
|
end
|
286
433
|
|
287
434
|
def auditing_enabled=(val)
|
288
435
|
Audited.store["#{table_name}_auditing_enabled"] = val
|
289
436
|
end
|
290
437
|
|
291
|
-
protected
|
292
438
|
def default_ignored_attributes
|
293
|
-
[primary_key, inheritance_column]
|
439
|
+
[primary_key, inheritance_column] | Audited.ignored_attributes
|
294
440
|
end
|
295
441
|
|
442
|
+
protected
|
443
|
+
|
296
444
|
def normalize_audited_options
|
297
445
|
audited_options[:on] = Array.wrap(audited_options[:on])
|
298
446
|
audited_options[:on] = [:create, :update, :destroy] if audited_options[:on].empty?
|
299
447
|
audited_options[:only] = Array.wrap(audited_options[:only]).map(&:to_s)
|
300
448
|
audited_options[:except] = Array.wrap(audited_options[:except]).map(&:to_s)
|
449
|
+
max_audits = audited_options[:max_audits] || Audited.max_audits
|
450
|
+
audited_options[:max_audits] = Integer(max_audits).abs if max_audits
|
451
|
+
end
|
452
|
+
|
453
|
+
def calculate_non_audited_columns
|
454
|
+
if audited_options[:only].present?
|
455
|
+
(column_names | default_ignored_attributes) - audited_options[:only]
|
456
|
+
elsif audited_options[:except].present?
|
457
|
+
default_ignored_attributes | audited_options[:except]
|
458
|
+
else
|
459
|
+
default_ignored_attributes
|
460
|
+
end
|
301
461
|
end
|
302
462
|
end
|
303
463
|
end
|