audited 4.10.0 → 5.2.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.

Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/buildlight.yml +15 -0
  3. data/.github/workflows/ci.yml +128 -0
  4. data/.standard.yml +5 -0
  5. data/Appraisals +20 -18
  6. data/CHANGELOG.md +90 -1
  7. data/Gemfile +1 -1
  8. data/README.md +52 -14
  9. data/Rakefile +6 -6
  10. data/gemfiles/rails50.gemfile +1 -0
  11. data/gemfiles/rails51.gemfile +1 -0
  12. data/gemfiles/rails52.gemfile +2 -1
  13. data/gemfiles/rails70.gemfile +10 -0
  14. data/lib/audited/audit.rb +24 -25
  15. data/lib/audited/auditor.rb +91 -56
  16. data/lib/audited/railtie.rb +16 -0
  17. data/lib/audited/rspec_matchers.rb +5 -3
  18. data/lib/audited/sweeper.rb +3 -10
  19. data/lib/audited/version.rb +3 -1
  20. data/lib/audited-rspec.rb +3 -1
  21. data/lib/audited.rb +33 -9
  22. data/lib/generators/audited/install_generator.rb +9 -7
  23. data/lib/generators/audited/migration.rb +12 -2
  24. data/lib/generators/audited/migration_helper.rb +3 -1
  25. data/lib/generators/audited/templates/add_association_to_audits.rb +2 -0
  26. data/lib/generators/audited/templates/add_comment_to_audits.rb +2 -0
  27. data/lib/generators/audited/templates/add_remote_address_to_audits.rb +2 -0
  28. data/lib/generators/audited/templates/add_request_uuid_to_audits.rb +2 -0
  29. data/lib/generators/audited/templates/add_version_to_auditable_index.rb +2 -0
  30. data/lib/generators/audited/templates/install.rb +2 -0
  31. data/lib/generators/audited/templates/rename_association_to_associated.rb +2 -0
  32. data/lib/generators/audited/templates/rename_changes_to_audited_changes.rb +2 -0
  33. data/lib/generators/audited/templates/rename_parent_to_association.rb +2 -0
  34. data/lib/generators/audited/templates/revert_polymorphic_indexes_order.rb +2 -0
  35. data/lib/generators/audited/upgrade_generator.rb +16 -14
  36. data/spec/audited/audit_spec.rb +68 -46
  37. data/spec/audited/auditor_spec.rb +310 -253
  38. data/spec/audited/sweeper_spec.rb +19 -19
  39. data/spec/audited_spec.rb +18 -0
  40. data/spec/audited_spec_helpers.rb +5 -7
  41. data/spec/rails_app/app/assets/config/manifest.js +2 -1
  42. data/spec/rails_app/config/application.rb +9 -3
  43. data/spec/rails_app/config/database.yml +3 -2
  44. data/spec/rails_app/config/environment.rb +1 -1
  45. data/spec/rails_app/config/environments/test.rb +10 -5
  46. data/spec/rails_app/config/initializers/secret_token.rb +2 -2
  47. data/spec/spec_helper.rb +14 -14
  48. data/spec/support/active_record/models.rb +24 -12
  49. data/spec/support/active_record/postgres/1_change_audited_changes_type_to_json.rb +1 -2
  50. data/spec/support/active_record/postgres/2_change_audited_changes_type_to_jsonb.rb +1 -2
  51. data/spec/support/active_record/schema.rb +25 -19
  52. data/test/db/version_1.rb +2 -2
  53. data/test/db/version_2.rb +2 -2
  54. data/test/db/version_3.rb +2 -3
  55. data/test/db/version_4.rb +2 -3
  56. data/test/db/version_5.rb +0 -1
  57. data/test/db/version_6.rb +1 -1
  58. data/test/install_generator_test.rb +18 -19
  59. data/test/test_helper.rb +5 -5
  60. data/test/upgrade_generator_test.rb +13 -18
  61. metadata +31 -31
  62. data/.rubocop.yml +0 -25
  63. data/.travis.yml +0 -63
  64. data/gemfiles/rails42.gemfile +0 -11
  65. data/spec/rails_app/app/controllers/application_controller.rb +0 -2
  66. data/spec/rails_app/config/environments/development.rb +0 -21
  67. data/spec/rails_app/config/environments/production.rb +0 -35
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Audited
2
4
  # Specify this act if you want changes to your model to be saved in an
3
5
  # audit table. This assumes there is an audits table ready.
@@ -11,7 +13,7 @@ module Audited
11
13
  #
12
14
  # See <tt>Audited::Auditor::ClassMethods#audited</tt>
13
15
  # for configuration options
14
- module Auditor #:nodoc:
16
+ module Auditor # :nodoc:
15
17
  extend ActiveSupport::Concern
16
18
 
17
19
  CALLBACKS = [:audit_create, :audit_update, :audit_destroy]
@@ -64,7 +66,7 @@ module Audited
64
66
  include Audited::Auditor::AuditedInstanceMethods
65
67
 
66
68
  class_attribute :audit_associated_with, instance_writer: false
67
- class_attribute :audited_options, instance_writer: false
69
+ class_attribute :audited_options, instance_writer: false
68
70
  attr_accessor :audit_version, :audit_comment
69
71
 
70
72
  self.audited_options = options
@@ -80,8 +82,8 @@ module Audited
80
82
  has_many :audits, -> { order(version: :asc) }, as: :auditable, class_name: Audited.audit_class.name, inverse_of: :auditable
81
83
  Audited.audit_class.audited_class_names << to_s
82
84
 
83
- after_create :audit_create if audited_options[:on].include?(:create)
84
- before_update :audit_update if audited_options[:on].include?(:update)
85
+ after_create :audit_create if audited_options[:on].include?(:create)
86
+ before_update :audit_update if audited_options[:on].include?(:update)
85
87
  before_destroy :audit_destroy if audited_options[:on].include?(:destroy)
86
88
 
87
89
  # Define and set after_audit and around_audit callbacks. This might be useful if you want
@@ -100,8 +102,8 @@ module Audited
100
102
  end
101
103
 
102
104
  module AuditedInstanceMethods
103
- REDACTED = '[REDACTED]'
104
-
105
+ REDACTED = "[REDACTED]"
106
+
105
107
  # Temporarily turns off auditing while saving.
106
108
  def save_without_auditing
107
109
  without_auditing { save }
@@ -142,7 +144,7 @@ module Audited
142
144
  def revisions(from_version = 1)
143
145
  return [] unless audits.from_version(from_version).exists?
144
146
 
145
- all_audits = audits.select([:audited_changes, :version]).to_a
147
+ all_audits = audits.select([:audited_changes, :version, :action]).to_a
146
148
  targeted_audits = all_audits.select { |audit| audit.version >= from_version }
147
149
 
148
150
  previous_attributes = reconstruct_attributes(all_audits - targeted_audits)
@@ -156,7 +158,7 @@ module Audited
156
158
  # Get a specific revision specified by the version number, or +:previous+
157
159
  # Returns nil for versions greater than revisions count
158
160
  def revision(version)
159
- if version == :previous || self.audits.last.version >= version
161
+ if version == :previous || audits.last.version >= version
160
162
  revision_with Audited.audit_class.reconstruct_attributes(audits_to(version))
161
163
  end
162
164
  end
@@ -170,15 +172,16 @@ module Audited
170
172
  # List of attributes that are audited.
171
173
  def audited_attributes
172
174
  audited_attributes = attributes.except(*self.class.non_audited_columns)
175
+ audited_attributes = redact_values(audited_attributes)
176
+ audited_attributes = filter_encrypted_attrs(audited_attributes)
173
177
  normalize_enum_changes(audited_attributes)
174
178
  end
175
179
 
176
180
  # Returns a list combined of record audits and associated audits.
177
181
  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)
182
+ Audited.audit_class.unscoped.where(auditable: self)
183
+ .or(Audited.audit_class.unscoped.where(associated: self))
184
+ .order(created_at: :desc)
182
185
  end
183
186
 
184
187
  # Combine multiple audits into one.
@@ -188,8 +191,13 @@ module Audited
188
191
  combine_target.comment = "#{combine_target.comment}\nThis audit is the result of multiple audits being combined."
189
192
 
190
193
  transaction do
191
- combine_target.save!
192
- audits_to_combine.unscope(:limit).where("version < ?", combine_target.version).delete_all
194
+ begin
195
+ combine_target.save!
196
+ audits_to_combine.unscope(:limit).where("version < ?", combine_target.version).delete_all
197
+ rescue ActiveRecord::Deadlocked
198
+ # Ignore Deadlocks, if the same record is getting its old audits combined more than once at the same time then
199
+ # both combining operations will be the same. Ignoring this error allows one of the combines to go through successfully.
200
+ end
193
201
  end
194
202
  end
195
203
 
@@ -198,12 +206,12 @@ module Audited
198
206
  def revision_with(attributes)
199
207
  dup.tap do |revision|
200
208
  revision.id = id
201
- revision.send :instance_variable_set, '@new_record', destroyed?
202
- revision.send :instance_variable_set, '@persisted', !destroyed?
203
- revision.send :instance_variable_set, '@readonly', false
204
- revision.send :instance_variable_set, '@destroyed', false
205
- revision.send :instance_variable_set, '@_destroyed', false
206
- revision.send :instance_variable_set, '@marked_for_destruction', false
209
+ revision.send :instance_variable_set, "@new_record", destroyed?
210
+ revision.send :instance_variable_set, "@persisted", !destroyed?
211
+ revision.send :instance_variable_set, "@readonly", false
212
+ revision.send :instance_variable_set, "@destroyed", false
213
+ revision.send :instance_variable_set, "@_destroyed", false
214
+ revision.send :instance_variable_set, "@marked_for_destruction", false
207
215
  Audited.audit_class.assign_revision_attributes(revision, attributes)
208
216
 
209
217
  # Remove any association proxies so that they will be recreated
@@ -232,17 +240,20 @@ module Audited
232
240
  end
233
241
 
234
242
  filtered_changes = redact_values(filtered_changes)
243
+ filtered_changes = filter_encrypted_attrs(filtered_changes)
235
244
  filtered_changes = normalize_enum_changes(filtered_changes)
236
245
  filtered_changes.to_hash
237
246
  end
238
247
 
239
248
  def normalize_enum_changes(changes)
249
+ return changes if Audited.store_synthesized_enums
250
+
240
251
  self.class.defined_enums.each do |name, values|
241
252
  if changes.has_key?(name)
242
253
  changes[name] = \
243
254
  if changes[name].is_a?(Array)
244
255
  changes[name].map { |v| values[v] }
245
- elsif rails_below?('5.0')
256
+ elsif rails_below?("5.0")
246
257
  changes[name]
247
258
  else
248
259
  values[changes[name]]
@@ -253,19 +264,36 @@ module Audited
253
264
  end
254
265
 
255
266
  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)
267
+ filter_attr_values(
268
+ audited_changes: filtered_changes,
269
+ attrs: Array(audited_options[:redacted]).map(&:to_s),
270
+ placeholder: audited_options[:redaction_value] || REDACTED
271
+ )
272
+ end
273
+
274
+ def filter_encrypted_attrs(filtered_changes)
275
+ filter_attr_values(
276
+ audited_changes: filtered_changes,
277
+ attrs: respond_to?(:encrypted_attributes) ? Array(encrypted_attributes).map(&:to_s) : []
278
+ )
279
+ end
280
+
281
+ # Replace values for given attrs to a placeholder and return modified hash
282
+ #
283
+ # @param audited_changes [Hash] Hash of changes to be saved to audited version record
284
+ # @param attrs [Array<String>] Array of attrs, values of which will be replaced to placeholder value
285
+ # @param placeholder [String] Placeholder to replace original attr values
286
+ def filter_attr_values(audited_changes: {}, attrs: [], placeholder: "[FILTERED]")
287
+ attrs.each do |attr|
288
+ next unless audited_changes.key?(attr)
289
+
290
+ changes = audited_changes[attr]
291
+ values = changes.is_a?(Array) ? changes.map { placeholder } : placeholder
292
+
293
+ audited_changes[attr] = values
266
294
  end
267
295
 
268
- filtered_changes
296
+ audited_changes
269
297
  end
270
298
 
271
299
  def rails_below?(rails_version)
@@ -274,41 +302,44 @@ module Audited
274
302
 
275
303
  def audits_to(version = nil)
276
304
  if version == :previous
277
- version = if self.audit_version
278
- self.audit_version - 1
279
- else
280
- previous = audits.descending.offset(1).first
281
- previous ? previous.version : 1
282
- end
305
+ version = if audit_version
306
+ audit_version - 1
307
+ else
308
+ previous = audits.descending.offset(1).first
309
+ previous ? previous.version : 1
310
+ end
283
311
  end
284
312
  audits.to_version(version)
285
313
  end
286
314
 
287
315
  def audit_create
288
- write_audit(action: 'create', audited_changes: audited_attributes,
289
- comment: audit_comment)
316
+ write_audit(action: "create", audited_changes: audited_attributes,
317
+ comment: audit_comment)
290
318
  end
291
319
 
292
320
  def audit_update
293
321
  unless (changes = audited_changes).empty? && (audit_comment.blank? || audited_options[:update_with_comment_only] == false)
294
- write_audit(action: 'update', audited_changes: changes,
295
- comment: audit_comment)
322
+ write_audit(action: "update", audited_changes: changes,
323
+ comment: audit_comment)
296
324
  end
297
325
  end
298
326
 
299
327
  def audit_destroy
300
- write_audit(action: 'destroy', audited_changes: audited_attributes,
301
- comment: audit_comment) unless new_record?
328
+ unless new_record?
329
+ write_audit(action: "destroy", audited_changes: audited_attributes,
330
+ comment: audit_comment)
331
+ end
302
332
  end
303
333
 
304
334
  def write_audit(attrs)
305
- attrs[:associated] = send(audit_associated_with) unless audit_associated_with.nil?
306
335
  self.audit_comment = nil
307
336
 
308
337
  if auditing_enabled
338
+ attrs[:associated] = send(audit_associated_with) unless audit_associated_with.nil?
339
+
309
340
  run_callbacks(:audit) {
310
341
  audit = audits.create(attrs)
311
- combine_audits_if_needed if attrs[:action] != 'create'
342
+ combine_audits_if_needed if attrs[:action] != "create"
312
343
  audit
313
344
  }
314
345
  end
@@ -316,14 +347,15 @@ module Audited
316
347
 
317
348
  def presence_of_audit_comment
318
349
  if comment_required_state?
319
- errors.add(:audit_comment, "Comment can't be blank!") unless audit_comment.present?
350
+ errors.add(:audit_comment, :blank) unless audit_comment.present?
320
351
  end
321
352
  end
322
353
 
323
354
  def comment_required_state?
324
355
  auditing_enabled &&
325
- ((audited_options[:on].include?(:create) && self.new_record?) ||
326
- (audited_options[:on].include?(:update) && self.persisted? && self.changed?))
356
+ audited_changes.present? &&
357
+ ((audited_options[:on].include?(:create) && new_record?) ||
358
+ (audited_options[:on].include?(:update) && persisted? && changed?))
327
359
  end
328
360
 
329
361
  def combine_audits_if_needed
@@ -336,8 +368,7 @@ module Audited
336
368
 
337
369
  def require_comment
338
370
  if auditing_enabled && audit_comment.blank?
339
- errors.add(:audit_comment, "Comment can't be blank!")
340
- return false if Rails.version.start_with?('4.')
371
+ errors.add(:audit_comment, :blank)
341
372
  throw(:abort)
342
373
  end
343
374
  end
@@ -347,7 +378,7 @@ module Audited
347
378
  end
348
379
 
349
380
  def auditing_enabled
350
- return run_conditional_check(audited_options[:if]) &&
381
+ run_conditional_check(audited_options[:if]) &&
351
382
  run_conditional_check(audited_options[:unless], matching: false) &&
352
383
  self.class.auditing_enabled
353
384
  end
@@ -365,7 +396,7 @@ module Audited
365
396
  audits.each { |audit| attributes.merge!(audit.new_attributes) }
366
397
  attributes
367
398
  end
368
- end # InstanceMethods
399
+ end
369
400
 
370
401
  module AuditedClassMethods
371
402
  # Returns an array of columns that are audited. See non_audited_columns
@@ -390,7 +421,7 @@ module Audited
390
421
  # end
391
422
  #
392
423
  def without_auditing
393
- auditing_was_enabled = auditing_enabled
424
+ auditing_was_enabled = class_auditing_enabled
394
425
  disable_auditing
395
426
  yield
396
427
  ensure
@@ -404,7 +435,7 @@ module Audited
404
435
  # end
405
436
  #
406
437
  def with_auditing
407
- auditing_was_enabled = auditing_enabled
438
+ auditing_was_enabled = class_auditing_enabled
408
439
  enable_auditing
409
440
  yield
410
441
  ensure
@@ -428,7 +459,7 @@ module Audited
428
459
  end
429
460
 
430
461
  def auditing_enabled
431
- Audited.store.fetch("#{table_name}_auditing_enabled", true) && Audited.auditing_enabled
462
+ class_auditing_enabled && Audited.auditing_enabled
432
463
  end
433
464
 
434
465
  def auditing_enabled=(val)
@@ -459,6 +490,10 @@ module Audited
459
490
  default_ignored_attributes
460
491
  end
461
492
  end
493
+
494
+ def class_auditing_enabled
495
+ Audited.store.fetch("#{table_name}_auditing_enabled", true)
496
+ end
462
497
  end
463
498
  end
464
499
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Audited
4
+ class Railtie < Rails::Railtie
5
+ initializer "audited.sweeper" do
6
+ ActiveSupport.on_load(:action_controller) do
7
+ if defined?(ActionController::Base)
8
+ ActionController::Base.around_action Audited::Sweeper.new
9
+ end
10
+ if defined?(ActionController::API)
11
+ ActionController::API.around_action Audited::Sweeper.new
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Audited
2
4
  module RspecMatchers
3
5
  # Ensure that the model is audited.
@@ -78,9 +80,9 @@ module Audited
78
80
  def description
79
81
  description = "audited"
80
82
  description += " associated with #{@options[:associated_with]}" if @options.key?(:associated_with)
81
- description += " only => #{@options[:only].join ', '}" if @options.key?(:only)
82
- description += " except => #{@options[:except].join(', ')}" if @options.key?(:except)
83
- description += " requires audit_comment" if @options.key?(:comment_required)
83
+ description += " only => #{@options[:only].join ", "}" if @options.key?(:only)
84
+ description += " except => #{@options[:except].join(", ")}" if @options.key?(:except)
85
+ description += " requires audit_comment" if @options.key?(:comment_required)
84
86
 
85
87
  description
86
88
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Audited
2
4
  class Sweeper
3
5
  STORED_DATA = {
@@ -10,7 +12,7 @@ module Audited
10
12
 
11
13
  def around(controller)
12
14
  self.controller = controller
13
- STORED_DATA.each { |k,m| store[k] = send(m) }
15
+ STORED_DATA.each { |k, m| store[k] = send(m) }
14
16
  yield
15
17
  ensure
16
18
  self.controller = nil
@@ -38,12 +40,3 @@ module Audited
38
40
  end
39
41
  end
40
42
  end
41
-
42
- ActiveSupport.on_load(:action_controller) do
43
- if defined?(ActionController::Base)
44
- ActionController::Base.around_action Audited::Sweeper.new
45
- end
46
- if defined?(ActionController::API)
47
- ActionController::API.around_action Audited::Sweeper.new
48
- end
49
- end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Audited
2
- VERSION = "4.10.0"
4
+ VERSION = "5.2.0"
3
5
  end
data/lib/audited-rspec.rb CHANGED
@@ -1,4 +1,6 @@
1
- require 'audited/rspec_matchers'
1
+ # frozen_string_literal: true
2
+
3
+ require "audited/rspec_matchers"
2
4
  module RSpec::Matchers
3
5
  include Audited::RspecMatchers
4
6
  end
data/lib/audited.rb CHANGED
@@ -1,16 +1,36 @@
1
- require 'active_record'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
2
4
 
3
5
  module Audited
4
6
  class << self
5
- attr_accessor :ignored_attributes, :current_user_method, :max_audits, :auditing_enabled
7
+ attr_accessor \
8
+ :auditing_enabled,
9
+ :current_user_method,
10
+ :ignored_attributes,
11
+ :max_audits,
12
+ :store_synthesized_enums
6
13
  attr_writer :audit_class
7
14
 
8
15
  def audit_class
9
- @audit_class ||= Audit
16
+ # The audit_class is set as String in the initializer. It can not be constantized during initialization and must
17
+ # be constantized at runtime. See https://github.com/collectiveidea/audited/issues/608
18
+ @audit_class = @audit_class.safe_constantize if @audit_class.is_a?(String)
19
+ @audit_class ||= Audited::Audit
10
20
  end
11
21
 
22
+ # remove audit_model in next major version it was only shortly present in 5.1.0
23
+ alias_method :audit_model, :audit_class
24
+ deprecate audit_model: "use Audited.audit_class instead of Audited.audit_model. This method will be removed."
25
+
12
26
  def store
13
- Thread.current[:audited_store] ||= {}
27
+ current_store_value = Thread.current.thread_variable_get(:audited_store)
28
+
29
+ if current_store_value.nil?
30
+ Thread.current.thread_variable_set(:audited_store, {})
31
+ else
32
+ current_store_value
33
+ end
14
34
  end
15
35
 
16
36
  def config
@@ -18,15 +38,19 @@ module Audited
18
38
  end
19
39
  end
20
40
 
21
- @ignored_attributes = %w(lock_version created_at updated_at created_on updated_on)
41
+ @ignored_attributes = %w[lock_version created_at updated_at created_on updated_on]
22
42
 
23
43
  @current_user_method = :current_user
24
44
  @auditing_enabled = true
45
+ @store_synthesized_enums = false
25
46
  end
26
47
 
27
- require 'audited/auditor'
28
- require 'audited/audit'
48
+ require "audited/auditor"
29
49
 
30
- ::ActiveRecord::Base.send :include, Audited::Auditor
50
+ ActiveSupport.on_load :active_record do
51
+ require "audited/audit"
52
+ include Audited::Auditor
53
+ end
31
54
 
32
- require 'audited/sweeper'
55
+ require "audited/sweeper"
56
+ require "audited/railtie"
@@ -1,9 +1,11 @@
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
- require 'generators/audited/migration_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+ require "rails/generators/migration"
5
+ require "active_record"
6
+ require "rails/generators/active_record"
7
+ require "generators/audited/migration"
8
+ require "generators/audited/migration_helper"
7
9
 
8
10
  module Audited
9
11
  module Generators
@@ -18,7 +20,7 @@ module Audited
18
20
  source_root File.expand_path("../templates", __FILE__)
19
21
 
20
22
  def copy_migration
21
- migration_template 'install.rb', 'db/migrate/install_audited.rb'
23
+ migration_template "install.rb", "db/migrate/install_audited.rb"
22
24
  end
23
25
  end
24
26
  end
@@ -1,15 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Audited
2
4
  module Generators
3
5
  module Migration
4
6
  # Implement the required interface for Rails::Generators::Migration.
5
- def next_migration_number(dirname) #:nodoc:
7
+ def next_migration_number(dirname) # :nodoc:
6
8
  next_migration_number = current_migration_number(dirname) + 1
7
- if ::ActiveRecord::Base.timestamped_migrations
9
+ if timestamped_migrations?
8
10
  [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
9
11
  else
10
12
  "%.3d" % next_migration_number
11
13
  end
12
14
  end
15
+
16
+ private
17
+
18
+ def timestamped_migrations?
19
+ (Rails.version >= "7.0") ?
20
+ ::ActiveRecord.timestamped_migrations :
21
+ ::ActiveRecord::Base.timestamped_migrations
22
+ end
13
23
  end
14
24
  end
15
25
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Audited
2
4
  module Generators
3
5
  module MigrationHelper
4
6
  def migration_parent
5
- Rails::VERSION::MAJOR == 4 ? 'ActiveRecord::Migration' : "ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]"
7
+ "ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]"
6
8
  end
7
9
  end
8
10
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  add_column :audits, :association_id, :integer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  add_column :audits, :comment, :string
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  add_column :audits, :remote_address, :string
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  add_column :audits, :request_uuid, :string
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  if index_exists?(:audits, [:auditable_type, :auditable_id], name: index_name)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  create_table :audits, :force => true do |t|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  if index_exists? :audits, [:association_id, :association_type], :name => 'association_index'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  rename_column :audits, :changes, :audited_changes
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  rename_column :audits, :auditable_parent_id, :association_id
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  fix_index_order_for [:associated_id, :associated_type], 'associated_index'