audited 4.10.0 → 5.0.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.standard.yml +5 -0
  3. data/.travis.yml +25 -21
  4. data/Appraisals +10 -18
  5. data/CHANGELOG.md +29 -1
  6. data/Gemfile +1 -1
  7. data/README.md +16 -3
  8. data/Rakefile +6 -6
  9. data/lib/audited-rspec.rb +3 -1
  10. data/lib/audited.rb +25 -8
  11. data/lib/audited/audit.rb +24 -25
  12. data/lib/audited/auditor.rb +45 -39
  13. data/lib/audited/railtie.rb +16 -0
  14. data/lib/audited/rspec_matchers.rb +5 -3
  15. data/lib/audited/sweeper.rb +3 -10
  16. data/lib/audited/version.rb +3 -1
  17. data/lib/generators/audited/install_generator.rb +9 -7
  18. data/lib/generators/audited/migration.rb +2 -0
  19. data/lib/generators/audited/migration_helper.rb +3 -1
  20. data/lib/generators/audited/templates/add_association_to_audits.rb +2 -0
  21. data/lib/generators/audited/templates/add_comment_to_audits.rb +2 -0
  22. data/lib/generators/audited/templates/add_remote_address_to_audits.rb +2 -0
  23. data/lib/generators/audited/templates/add_request_uuid_to_audits.rb +2 -0
  24. data/lib/generators/audited/templates/add_version_to_auditable_index.rb +2 -0
  25. data/lib/generators/audited/templates/install.rb +2 -0
  26. data/lib/generators/audited/templates/rename_association_to_associated.rb +2 -0
  27. data/lib/generators/audited/templates/rename_changes_to_audited_changes.rb +2 -0
  28. data/lib/generators/audited/templates/rename_parent_to_association.rb +2 -0
  29. data/lib/generators/audited/templates/revert_polymorphic_indexes_order.rb +2 -0
  30. data/lib/generators/audited/upgrade_generator.rb +16 -14
  31. data/spec/audited/audit_spec.rb +67 -45
  32. data/spec/audited/auditor_spec.rb +284 -253
  33. data/spec/audited/sweeper_spec.rb +19 -19
  34. data/spec/audited_spec.rb +18 -0
  35. data/spec/audited_spec_helpers.rb +5 -7
  36. data/spec/rails_app/app/assets/config/manifest.js +2 -1
  37. data/spec/rails_app/config/application.rb +3 -3
  38. data/spec/rails_app/config/environment.rb +1 -1
  39. data/spec/rails_app/config/environments/test.rb +5 -5
  40. data/spec/rails_app/config/initializers/secret_token.rb +2 -2
  41. data/spec/spec_helper.rb +14 -14
  42. data/spec/support/active_record/models.rb +16 -12
  43. data/spec/support/active_record/postgres/1_change_audited_changes_type_to_json.rb +1 -2
  44. data/spec/support/active_record/postgres/2_change_audited_changes_type_to_jsonb.rb +1 -2
  45. data/spec/support/active_record/schema.rb +25 -19
  46. data/test/db/version_1.rb +2 -2
  47. data/test/db/version_2.rb +2 -2
  48. data/test/db/version_3.rb +2 -3
  49. data/test/db/version_4.rb +2 -3
  50. data/test/db/version_5.rb +0 -1
  51. data/test/db/version_6.rb +1 -1
  52. data/test/install_generator_test.rb +18 -19
  53. data/test/test_helper.rb +5 -5
  54. data/test/upgrade_generator_test.rb +13 -18
  55. metadata +20 -22
  56. data/.rubocop.yml +0 -25
  57. data/gemfiles/rails42.gemfile +0 -11
  58. data/spec/rails_app/app/controllers/application_controller.rb +0 -2
  59. data/spec/rails_app/config/environments/development.rb +0 -21
  60. data/spec/rails_app/config/environments/production.rb +0 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e774f1f27e84aaa6f3ad9160eaba9b0e5eda0df9202cb5acaf405de13071c4d3
4
- data.tar.gz: affeec219575b7032c73f03d69d839aeb7ad81ab7c53e2e636bea0243d66ac8f
3
+ metadata.gz: 52f7d297a07e673c3f45866a6ec8cb02c6228cdd6c1c0f7d1043c5eacfd104e2
4
+ data.tar.gz: 2776fa266fb211bfc0c0d939fd001d862408196cd0e902e0417f8a3696ee4ba1
5
5
  SHA512:
6
- metadata.gz: df852876685671788eeec0cd604a5771ed5bd096d466c10f1b9798774681c03749b2280bf4794d0cef707080c4f2e22464adbb90ac39f077132a0d3630c85c8c
7
- data.tar.gz: bf555f179f6c33d4493aa984c1163e1ae2bcf7985b1ff7fecbe52012b3d2140c364098478aca57817c8991747a4009e4b184e63227621dc752cd8fe5ccf8a516
6
+ metadata.gz: 172a29b25cdb1dfdf5c04ce42448e7ba1b864347a7783fb06bdbc277f4fa3dfe18d75c03d37ee7fd2ad93e2a78d9a34b02a8d08c67a0f46518c202d2b3534ec2
7
+ data.tar.gz: 8b86c7befab204c98b72f81f8227991d821c4f173d32191e256cdad0bb4cd997bc9c0c7715bacae03539a919ec57cb25e6911e855f38845bd7389318fab9fcba
data/.standard.yml ADDED
@@ -0,0 +1,5 @@
1
+ ruby_version: 2.3
2
+ ignore:
3
+ - lib/generators/audited/templates/**/*
4
+ - vendor/bundle/**/*
5
+ - gemfiles/vendor/bundle/**/*
data/.travis.yml CHANGED
@@ -1,10 +1,12 @@
1
1
  language: ruby
2
2
  cache: bundler
3
3
  rvm:
4
- - 2.3.7
5
- - 2.4.4
6
- - 2.5.1
7
- - 2.6.3
4
+ - 2.3.8
5
+ - 2.4.10
6
+ - 2.5.9
7
+ - 2.6.7
8
+ - 2.7.3
9
+ - 3.0.1
8
10
  - ruby-head
9
11
  env:
10
12
  - DB=SQLITE
@@ -17,15 +19,7 @@ services:
17
19
  before_install:
18
20
  # https://github.com/travis-ci/travis-ci/issues/8978
19
21
  - "travis_retry gem update --system"
20
- # Rails 4.2 has a bundler 1.x requirement
21
- - if [ $BUNDLE_GEMFILE = $PWD/gemfiles/rails42.gemfile ]; then
22
- travis_retry gem install -v '1.17.3' bundler;
23
- bundle _1.17.3_ install;
24
- else
25
- travis_retry gem install bundler;
26
- fi
27
22
  gemfile:
28
- - gemfiles/rails42.gemfile
29
23
  - gemfiles/rails50.gemfile
30
24
  - gemfiles/rails51.gemfile
31
25
  - gemfiles/rails52.gemfile
@@ -33,20 +27,30 @@ gemfile:
33
27
  - gemfiles/rails61.gemfile
34
28
  matrix:
35
29
  include:
36
- - rvm: 2.6.3
37
- script: bundle exec rubocop --parallel
38
- env: DB=rubocop # make travis build display nicer
30
+ - rvm: 2.6.7
31
+ script: bundle exec standardrb
32
+ env: DB=standard # make travis build display nicer
39
33
  exclude:
40
- - rvm: 2.3.7
34
+ - rvm: 2.3.8
41
35
  gemfile: gemfiles/rails61.gemfile
42
- - rvm: 2.4.4
36
+ - rvm: 2.4.10
43
37
  gemfile: gemfiles/rails61.gemfile
44
- - rvm: 2.3.7
38
+ - rvm: 2.3.8
45
39
  gemfile: gemfiles/rails60.gemfile
46
- - rvm: 2.4.4
40
+ - rvm: 2.4.10
47
41
  gemfile: gemfiles/rails60.gemfile
48
- - rvm: 2.6.3
42
+ - rvm: 2.6.7
49
43
  gemfile: gemfiles/rails42.gemfile
44
+ - rvm: 2.7.3
45
+ gemfile: gemfiles/rails42.gemfile
46
+ - rvm: 3.0.1
47
+ gemfile: gemfiles/rails42.gemfile
48
+ - rvm: 3.0.1
49
+ gemfile: gemfiles/rails50.gemfile
50
+ - rvm: 3.0.1
51
+ gemfile: gemfiles/rails51.gemfile
52
+ - rvm: 3.0.1
53
+ gemfile: gemfiles/rails52.gemfile
50
54
  - rvm: ruby-head
51
55
  gemfile: gemfiles/rails42.gemfile
52
56
  allow_failures:
@@ -59,5 +63,5 @@ branches:
59
63
  notifications:
60
64
  webhooks:
61
65
  urls:
62
- - http://buildlight.collectiveidea.com/
66
+ - https://buildlight.collectiveidea.com/
63
67
  on_start: always
data/Appraisals CHANGED
@@ -1,44 +1,36 @@
1
1
  # Include DB adapters matching the version requirements in
2
2
  # rails/activerecord/lib/active_record/connection_adapters/*adapter.rb
3
3
 
4
- appraise 'rails42' do
5
- gem 'rails', '~> 4.2.0'
6
- gem 'protected_attributes'
7
- gem "mysql2", ">= 0.3.13", "< 0.6.0"
8
- gem "pg", "~> 0.15"
9
- gem "sqlite3", "~> 1.3.6"
10
- end
11
-
12
- appraise 'rails50' do
13
- gem 'rails', '~> 5.0.0'
4
+ appraise "rails50" do
5
+ gem "rails", "~> 5.0.0"
14
6
  gem "mysql2", ">= 0.3.18", "< 0.6.0"
15
7
  gem "pg", ">= 0.18", "< 2.0"
16
8
  gem "sqlite3", "~> 1.3.6"
17
9
  end
18
10
 
19
- appraise 'rails51' do
20
- gem 'rails', '~> 5.1.4'
11
+ appraise "rails51" do
12
+ gem "rails", "~> 5.1.4"
21
13
  gem "mysql2", ">= 0.3.18", "< 0.6.0"
22
14
  gem "pg", ">= 0.18", "< 2.0"
23
15
  gem "sqlite3", "~> 1.3.6"
24
16
  end
25
17
 
26
- appraise 'rails52' do
27
- gem 'rails', '>= 5.2.0', '< 5.3'
18
+ appraise "rails52" do
19
+ gem "rails", ">= 5.2.0", "< 5.3"
28
20
  gem "mysql2", ">= 0.4.4", "< 0.6.0"
29
21
  gem "pg", ">= 0.18", "< 2.0"
30
22
  gem "sqlite3", "~> 1.3.6"
31
23
  end
32
24
 
33
- appraise 'rails60' do
34
- gem 'rails', '>= 6.0.0', '< 6.1'
25
+ appraise "rails60" do
26
+ gem "rails", ">= 6.0.0", "< 6.1"
35
27
  gem "mysql2", ">= 0.4.4"
36
28
  gem "pg", ">= 0.18", "< 2.0"
37
29
  gem "sqlite3", "~> 1.4"
38
30
  end
39
31
 
40
- appraise 'rails61' do
41
- gem 'rails', '>= 6.1.0', '< 6.2'
32
+ appraise "rails61" do
33
+ gem "rails", ">= 6.1.0", "< 6.2"
42
34
  gem "mysql2", ">= 0.4.4"
43
35
  gem "pg", ">= 1.1", "< 2.0"
44
36
  gem "sqlite3", "~> 1.4"
data/CHANGELOG.md CHANGED
@@ -1,6 +1,34 @@
1
1
  # Audited ChangeLog
2
2
 
3
- ## Unreleased
3
+ ## 5.0.0 (2021-06-10)
4
+
5
+ Improved
6
+
7
+ - Fixes an issue where array attributes were not deserialized properly - @cfeckardt, @yuki24
8
+ [#448](https://github.com/collectiveidea/audited/pull/448)
9
+ [#576](https://github.com/collectiveidea/audited/pull/576)
10
+ - Improve error message on audit_comment and allow for i18n override - @james
11
+ [#523](https://github.com/collectiveidea/audited/pull/523/)
12
+ - Don't require a comment if only non-audited fields are changed - @james
13
+ [#522](https://github.com/collectiveidea/audited/pull/522/)
14
+ - Readme updates - @gourshete
15
+ [#525](https://github.com/collectiveidea/audited/pull/525)
16
+ - Allow restoring previous enum behavior with flag - @travisofthenorth
17
+ [#526](https://github.com/collectiveidea/audited/pull/526)
18
+ - Follow Rails Autoloading conventions - @duncanjbrown
19
+ [#532](https://github.com/collectiveidea/audited/pull/532)
20
+ - Fix own_and_associated_audits for STI Models - @eric-hemasystems
21
+ [#533](https://github.com/collectiveidea/audited/pull/533)
22
+ - Rails 6.1 Improvements - @okuramasafumi, @marcrohloff
23
+ [#563](https://github.com/collectiveidea/audited/pull/563)
24
+ [#544](https://github.com/collectiveidea/audited/pull/544)
25
+ - Use Thread local variables instead of Fibers - @arathunku
26
+ [#568](https://github.com/collectiveidea/audited/pull/568)
27
+
28
+ Changed
29
+
30
+ - Drop support for Rails 4 - @travisofthenorth
31
+ [#527](https://github.com/collectiveidea/audited/pull/527)
4
32
 
5
33
  ## 4.10.0 (2021-01-07)
6
34
 
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec name: "audited"
data/README.md CHANGED
@@ -1,10 +1,13 @@
1
1
  Audited [![Build Status](https://secure.travis-ci.org/collectiveidea/audited.svg)](http://travis-ci.org/collectiveidea/audited) [![Code Climate](https://codeclimate.com/github/collectiveidea/audited.svg)](https://codeclimate.com/github/collectiveidea/audited) [![Security](https://hakiri.io/github/collectiveidea/audited/master.svg)](https://hakiri.io/github/collectiveidea/audited/master)
2
+ [![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
2
3
  =======
3
4
 
4
5
  **Audited** (previously acts_as_audited) is an ORM extension that logs all changes to your models. Audited can also record who made those changes, save comments and associate models related to the changes.
5
6
 
6
- Audited currently (4.x) works with Rails 6.1, Rails 6.0, 5.2, 5.1, 5.0 and 4.2.
7
7
 
8
+ Audited currently (5.x) works with Rails 6.1, 6.0, 5.2, 5.1, and 5.0.
9
+
10
+ For Rails 4, use gem version 4.x
8
11
  For Rails 3, use gem version 3.0 or see the [3.0-stable branch](https://github.com/collectiveidea/audited/tree/3.0-stable).
9
12
 
10
13
  ## Supported Rubies
@@ -153,7 +156,7 @@ end
153
156
 
154
157
  ### Limiting stored audits
155
158
 
156
- You can limit the number of audits stored for your model. To configure limiting for all audited models, put the following in an initializer:
159
+ You can limit the number of audits stored for your model. To configure limiting for all audited models, put the following in an initializer file (`config/initializers/audited.rb`):
157
160
 
158
161
  ```ruby
159
162
  Audited.max_audits = 10 # keep only 10 latest audits
@@ -192,7 +195,7 @@ class PostsController < ApplicationController
192
195
  end
193
196
  ```
194
197
 
195
- To use a method other than `current_user`, put the following in an initializer:
198
+ To use a method other than `current_user`, put the following in an initializer file (`config/initializers/audited.rb`):
196
199
 
197
200
  ```ruby
198
201
  Audited.current_user_method = :authenticated_user
@@ -388,6 +391,16 @@ Audited.config do |config|
388
391
  end
389
392
  ```
390
393
 
394
+ ### Enum Storage
395
+
396
+ In 4.10, the default behavior for enums changed from storing the value synthesized by Rails to the value stored in the DB. You can restore the previous behavior by setting the store_synthesized_enums configuration value:
397
+
398
+ ```ruby
399
+ # config/initializers/audited.rb
400
+
401
+ Audited.store_synthesized_enums = true
402
+ ```
403
+
391
404
  ## Support
392
405
 
393
406
  You can find documentation at: http://rdoc.info/github/collectiveidea/audited
data/Rakefile CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env rake
2
2
 
3
- require 'bundler/gem_helper'
4
- require 'rspec/core/rake_task'
5
- require 'rake/testtask'
6
- require 'appraisal'
3
+ require "bundler/gem_helper"
4
+ require "rspec/core/rake_task"
5
+ require "rake/testtask"
6
+ require "appraisal"
7
7
 
8
- Bundler::GemHelper.install_tasks(name: 'audited')
8
+ Bundler::GemHelper.install_tasks(name: "audited")
9
9
 
10
10
  RSpec::Core::RakeTask.new(:spec)
11
11
 
12
12
  Rake::TestTask.new do |t|
13
13
  t.libs << "test"
14
- t.test_files = FileList['test/**/*_test.rb']
14
+ t.test_files = FileList["test/**/*_test.rb"]
15
15
  t.verbose = true
16
16
  end
17
17
 
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,8 +1,15 @@
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
@@ -10,7 +17,13 @@ module Audited
10
17
  end
11
18
 
12
19
  def store
13
- Thread.current[:audited_store] ||= {}
20
+ current_store_value = Thread.current.thread_variable_get(:audited_store)
21
+
22
+ if current_store_value.nil?
23
+ Thread.current.thread_variable_set(:audited_store, {})
24
+ else
25
+ current_store_value
26
+ end
14
27
  end
15
28
 
16
29
  def config
@@ -18,15 +31,19 @@ module Audited
18
31
  end
19
32
  end
20
33
 
21
- @ignored_attributes = %w(lock_version created_at updated_at created_on updated_on)
34
+ @ignored_attributes = %w[lock_version created_at updated_at created_on updated_on]
22
35
 
23
36
  @current_user_method = :current_user
24
37
  @auditing_enabled = true
38
+ @store_synthesized_enums = false
25
39
  end
26
40
 
27
- require 'audited/auditor'
28
- require 'audited/audit'
41
+ require "audited/auditor"
42
+ require "audited/audit"
29
43
 
30
- ::ActiveRecord::Base.send :include, Audited::Auditor
44
+ ActiveSupport.on_load :active_record do
45
+ include Audited::Auditor
46
+ end
31
47
 
32
- require 'audited/sweeper'
48
+ require "audited/sweeper"
49
+ require "audited/railtie"
data/lib/audited/audit.rb CHANGED
@@ -1,4 +1,6 @@
1
- require 'set'
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
2
4
 
3
5
  module Audited
4
6
  # Audit saves the changes to ActiveRecord models. It has the following attributes:
@@ -38,8 +40,8 @@ module Audited
38
40
  end
39
41
 
40
42
  class Audit < ::ActiveRecord::Base
41
- belongs_to :auditable, polymorphic: true
42
- belongs_to :user, polymorphic: true
43
+ belongs_to :auditable, polymorphic: true
44
+ belongs_to :user, polymorphic: true
43
45
  belongs_to :associated, polymorphic: true
44
46
 
45
47
  before_create :set_version_number, :set_audit_user, :set_request_uuid, :set_remote_address
@@ -49,16 +51,16 @@ module Audited
49
51
 
50
52
  serialize :audited_changes, YAMLIfTextColumnType
51
53
 
52
- scope :ascending, ->{ reorder(version: :asc) }
53
- scope :descending, ->{ reorder(version: :desc)}
54
- scope :creates, ->{ where(action: 'create')}
55
- scope :updates, ->{ where(action: 'update')}
56
- scope :destroys, ->{ where(action: 'destroy')}
54
+ scope :ascending, -> { reorder(version: :asc) }
55
+ scope :descending, -> { reorder(version: :desc) }
56
+ scope :creates, -> { where(action: "create") }
57
+ scope :updates, -> { where(action: "update") }
58
+ scope :destroys, -> { where(action: "destroy") }
57
59
 
58
- scope :up_until, ->(date_or_time){ where("created_at <= ?", date_or_time) }
59
- scope :from_version, ->(version){ where('version >= ?', version) }
60
- scope :to_version, ->(version){ where('version <= ?', version) }
61
- scope :auditable_finder, ->(auditable_id, auditable_type){ where(auditable_id: auditable_id, auditable_type: auditable_type)}
60
+ scope :up_until, ->(date_or_time) { where("created_at <= ?", date_or_time) }
61
+ scope :from_version, ->(version) { where("version >= ?", version) }
62
+ scope :to_version, ->(version) { where("version <= ?", version) }
63
+ scope :auditable_finder, ->(auditable_id, auditable_type) { where(auditable_id: auditable_id, auditable_type: auditable_type) }
62
64
  # Return all audits older than the current one.
63
65
  def ancestors
64
66
  self.class.ascending.auditable_finder(auditable_id, auditable_type).to_version(version)
@@ -75,31 +77,28 @@ module Audited
75
77
 
76
78
  # Returns a hash of the changed attributes with the new values
77
79
  def new_attributes
78
- (audited_changes || {}).inject({}.with_indifferent_access) do |attrs, (attr, values)|
79
- attrs[attr] = values.is_a?(Array) ? values.last : values
80
- attrs
80
+ (audited_changes || {}).each_with_object({}.with_indifferent_access) do |(attr, values), attrs|
81
+ attrs[attr] = (action == "update" ? values.last : values)
81
82
  end
82
83
  end
83
84
 
84
85
  # Returns a hash of the changed attributes with the old values
85
86
  def old_attributes
86
- (audited_changes || {}).inject({}.with_indifferent_access) do |attrs, (attr, values)|
87
- attrs[attr] = Array(values).first
88
-
89
- attrs
87
+ (audited_changes || {}).each_with_object({}.with_indifferent_access) do |(attr, values), attrs|
88
+ attrs[attr] = (action == "update" ? values.first : values)
90
89
  end
91
90
  end
92
91
 
93
92
  # Allows user to undo changes
94
93
  def undo
95
94
  case action
96
- when 'create'
95
+ when "create"
97
96
  # destroys a newly created record
98
97
  auditable.destroy!
99
- when 'destroy'
98
+ when "destroy"
100
99
  # creates a new record with the destroyed record attributes
101
100
  auditable_type.constantize.create!(audited_changes)
102
- when 'update'
101
+ when "update"
103
102
  # changes back attributes
104
103
  auditable.update!(audited_changes.transform_values(&:first))
105
104
  else
@@ -147,7 +146,7 @@ module Audited
147
146
  audits.each_with_object({}) do |audit, all|
148
147
  all.merge!(audit.new_attributes)
149
148
  all[:audit_version] = audit.version
150
- end
149
+ end
151
150
  end
152
151
 
153
152
  # @private
@@ -172,10 +171,10 @@ module Audited
172
171
  private
173
172
 
174
173
  def set_version_number
175
- if action == 'create'
174
+ if action == "create"
176
175
  self.version = 1
177
176
  else
178
- collection = Rails::VERSION::MAJOR == 6 ? self.class.unscoped : self.class
177
+ collection = Rails::VERSION::MAJOR >= 6 ? self.class.unscoped : self.class
179
178
  max = collection.auditable_finder(auditable_id, auditable_type).maximum(:version) || 0
180
179
  self.version = max + 1
181
180
  end
@@ -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.
@@ -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
@@ -176,9 +178,9 @@ module Audited
176
178
  # Returns a list combined of record audits and associated audits.
177
179
  def own_and_associated_audits
178
180
  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)
181
+ .where("(auditable_type = :type AND auditable_id = :id) OR (associated_type = :type AND associated_id = :id)",
182
+ type: self.class.base_class.name, id: id)
183
+ .order(created_at: :desc)
182
184
  end
183
185
 
184
186
  # Combine multiple audits into one.
@@ -198,12 +200,12 @@ module Audited
198
200
  def revision_with(attributes)
199
201
  dup.tap do |revision|
200
202
  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
203
+ revision.send :instance_variable_set, "@new_record", destroyed?
204
+ revision.send :instance_variable_set, "@persisted", !destroyed?
205
+ revision.send :instance_variable_set, "@readonly", false
206
+ revision.send :instance_variable_set, "@destroyed", false
207
+ revision.send :instance_variable_set, "@_destroyed", false
208
+ revision.send :instance_variable_set, "@marked_for_destruction", false
207
209
  Audited.audit_class.assign_revision_attributes(revision, attributes)
208
210
 
209
211
  # Remove any association proxies so that they will be recreated
@@ -237,12 +239,14 @@ module Audited
237
239
  end
238
240
 
239
241
  def normalize_enum_changes(changes)
242
+ return changes if Audited.store_synthesized_enums
243
+
240
244
  self.class.defined_enums.each do |name, values|
241
245
  if changes.has_key?(name)
242
246
  changes[name] = \
243
247
  if changes[name].is_a?(Array)
244
248
  changes[name].map { |v| values[v] }
245
- elsif rails_below?('5.0')
249
+ elsif rails_below?("5.0")
246
250
  changes[name]
247
251
  else
248
252
  values[changes[name]]
@@ -256,12 +260,12 @@ module Audited
256
260
  [audited_options[:redacted]].flatten.compact.each do |option|
257
261
  changes = filtered_changes[option.to_s]
258
262
  new_value = audited_options[:redaction_value] || REDACTED
259
- if changes.is_a? Array
260
- values = changes.map { new_value }
263
+ values = if changes.is_a? Array
264
+ changes.map { new_value }
261
265
  else
262
- values = new_value
266
+ new_value
263
267
  end
264
- hash = Hash[option.to_s, values]
268
+ hash = {option.to_s => values}
265
269
  filtered_changes.merge!(hash)
266
270
  end
267
271
 
@@ -274,31 +278,33 @@ module Audited
274
278
 
275
279
  def audits_to(version = nil)
276
280
  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
281
+ version = if audit_version
282
+ audit_version - 1
283
+ else
284
+ previous = audits.descending.offset(1).first
285
+ previous ? previous.version : 1
286
+ end
283
287
  end
284
288
  audits.to_version(version)
285
289
  end
286
290
 
287
291
  def audit_create
288
- write_audit(action: 'create', audited_changes: audited_attributes,
292
+ write_audit(action: "create", audited_changes: audited_attributes,
289
293
  comment: audit_comment)
290
294
  end
291
295
 
292
296
  def audit_update
293
297
  unless (changes = audited_changes).empty? && (audit_comment.blank? || audited_options[:update_with_comment_only] == false)
294
- write_audit(action: 'update', audited_changes: changes,
298
+ write_audit(action: "update", audited_changes: changes,
295
299
  comment: audit_comment)
296
300
  end
297
301
  end
298
302
 
299
303
  def audit_destroy
300
- write_audit(action: 'destroy', audited_changes: audited_attributes,
301
- comment: audit_comment) unless new_record?
304
+ unless new_record?
305
+ write_audit(action: "destroy", audited_changes: audited_attributes,
306
+ comment: audit_comment)
307
+ end
302
308
  end
303
309
 
304
310
  def write_audit(attrs)
@@ -308,7 +314,7 @@ module Audited
308
314
  if auditing_enabled
309
315
  run_callbacks(:audit) {
310
316
  audit = audits.create(attrs)
311
- combine_audits_if_needed if attrs[:action] != 'create'
317
+ combine_audits_if_needed if attrs[:action] != "create"
312
318
  audit
313
319
  }
314
320
  end
@@ -316,14 +322,15 @@ module Audited
316
322
 
317
323
  def presence_of_audit_comment
318
324
  if comment_required_state?
319
- errors.add(:audit_comment, "Comment can't be blank!") unless audit_comment.present?
325
+ errors.add(:audit_comment, :blank) unless audit_comment.present?
320
326
  end
321
327
  end
322
328
 
323
329
  def comment_required_state?
324
330
  auditing_enabled &&
325
- ((audited_options[:on].include?(:create) && self.new_record?) ||
326
- (audited_options[:on].include?(:update) && self.persisted? && self.changed?))
331
+ audited_changes.present? &&
332
+ ((audited_options[:on].include?(:create) && new_record?) ||
333
+ (audited_options[:on].include?(:update) && persisted? && changed?))
327
334
  end
328
335
 
329
336
  def combine_audits_if_needed
@@ -336,8 +343,7 @@ module Audited
336
343
 
337
344
  def require_comment
338
345
  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.')
346
+ errors.add(:audit_comment, :blank)
341
347
  throw(:abort)
342
348
  end
343
349
  end
@@ -347,7 +353,7 @@ module Audited
347
353
  end
348
354
 
349
355
  def auditing_enabled
350
- return run_conditional_check(audited_options[:if]) &&
356
+ run_conditional_check(audited_options[:if]) &&
351
357
  run_conditional_check(audited_options[:unless], matching: false) &&
352
358
  self.class.auditing_enabled
353
359
  end
@@ -365,7 +371,7 @@ module Audited
365
371
  audits.each { |audit| attributes.merge!(audit.new_attributes) }
366
372
  attributes
367
373
  end
368
- end # InstanceMethods
374
+ end
369
375
 
370
376
  module AuditedClassMethods
371
377
  # Returns an array of columns that are audited. See non_audited_columns