diff --git a/.gitignore b/.gitignore index f0089ff..08cbf90 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ Gemfile.lock log/*.log pkg/ +spec/examples.txt spec/dummy/log/*.log spec/dummy/tmp/ /gemfiles/*.gemfile.lock diff --git a/README.md b/README.md index 5b2683b..0e537c4 100644 --- a/README.md +++ b/README.md @@ -345,6 +345,15 @@ Journaled::AuditLog.with_snapshots do end ``` +Snapshots can also be enabled globally for all _deletion_ operations. Since +`changes` will be empty on deletion, you should consider using this if you care +about the contents of any records being deleted (and/or don't have a full audit +trail from their time of creation): + +```ruby +Journaled::AuditLog.snapshot_on_deletion = true +``` + Events with snapshots will continue to populate the `changes` field, but will additionally contain a snapshot with the full state of the user: diff --git a/app/models/journaled/audit_log/event.rb b/app/models/journaled/audit_log/event.rb index 165ab6a..856578d 100644 --- a/app/models/journaled/audit_log/event.rb +++ b/app/models/journaled/audit_log/event.rb @@ -58,7 +58,8 @@ def changes end def snapshot - filtered_attributes if record._log_snapshot || AuditLog.snapshots_enabled + filtered_attributes if record._log_snapshot || AuditLog.snapshots_enabled || + (database_operation == 'delete' && AuditLog.snapshot_on_deletion) end def actor diff --git a/lib/journaled/audit_log.rb b/lib/journaled/audit_log.rb index 78ca40a..e59d77a 100644 --- a/lib/journaled/audit_log.rb +++ b/lib/journaled/audit_log.rb @@ -18,6 +18,7 @@ module AuditLog mattr_accessor(:default_enqueue_opts) { {} } mattr_accessor(:excluded_classes) { DEFAULT_EXCLUDED_CLASSES.dup } thread_mattr_accessor(:snapshots_enabled) { false } + thread_mattr_accessor(:snapshot_on_deletion) { false } thread_mattr_accessor(:_disabled) { false } thread_mattr_accessor(:_force) { false } diff --git a/lib/journaled/version.rb b/lib/journaled/version.rb index 9f26ec8..7b5b5a8 100644 --- a/lib/journaled/version.rb +++ b/lib/journaled/version.rb @@ -1,3 +1,3 @@ module Journaled - VERSION = "5.1.1".freeze + VERSION = "5.2.0".freeze end diff --git a/spec/lib/journaled/audit_log_spec.rb b/spec/lib/journaled/audit_log_spec.rb index d49cd8c..d3e57b4 100644 --- a/spec/lib/journaled/audit_log_spec.rb +++ b/spec/lib/journaled/audit_log_spec.rb @@ -389,6 +389,23 @@ def assign_attrs(**attrs) end end end + + context 'and snapshotting is enabled only on deletion' do + subject { MyModel.new(name: 'bob') } + + before do + described_class.snapshot_on_deletion = true + end + + it 'emits snapshots through the lifecycle of the object, and filters the expected fields' do + expect { subject.save } + .to not_journal_event_including(snapshot: { all: 'attributes', password: '[FILTERED]' }) + expect { subject.update(name: 'robert') } + .to not_journal_event_including(snapshot: { all: 'attributes', password: '[FILTERED]' }) + expect { subject.destroy } + .to journal_event_including(snapshot: { all: 'attributes', password: '[FILTERED]' }) + end + end end context 'and a field is ignored' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7a091e5..c2d3eeb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -24,6 +24,7 @@ mocks.verify_partial_doubles = true end + config.example_status_persistence_file_path = 'spec/examples.txt' config.order = :random end