diff --git a/lib/audited/auditor.rb b/lib/audited/auditor.rb index c9c867ae..a164f72a 100644 --- a/lib/audited/auditor.rb +++ b/lib/audited/auditor.rb @@ -59,9 +59,16 @@ module ClassMethods # end # def audited(options = {}) - # don't allow multiple calls - return if included_modules.include?(Audited::Auditor::AuditedInstanceMethods) + audited? ? update_audited_options(options) : set_audit(options) + end + + private + + def audited? + included_modules.include?(Audited::Auditor::AuditedInstanceMethods) + end + def set_audit(options) extend Audited::Auditor::AuditedClassMethods include Audited::Auditor::AuditedInstanceMethods @@ -69,10 +76,7 @@ def audited(options = {}) class_attribute :audited_options, instance_writer: false attr_accessor :audit_version, :audit_comment - self.audited_options = options - normalize_audited_options - - self.audit_associated_with = audited_options[:associated_with] + set_audited_options(options) if audited_options[:comment_required] validate :presence_of_audit_comment @@ -100,6 +104,18 @@ def audited(options = {}) def has_associated_audits has_many :associated_audits, as: :associated, class_name: Audited.audit_class.name end + + def update_audited_options(new_options) + previous_audit_options = self.audited_options + set_audited_options(new_options) + self.reset_audited_columns + end + + def set_audited_options(options) + self.audited_options = options + normalize_audited_options + self.audit_associated_with = audited_options[:associated_with] + end end module AuditedInstanceMethods @@ -530,6 +546,11 @@ def calculate_non_audited_columns def class_auditing_enabled Audited.store.fetch("#{table_name}_auditing_enabled", true) end + + def reset_audited_columns + @audited_columns = nil + @non_audited_columns = nil + end end end end diff --git a/spec/audited/auditor_spec.rb b/spec/audited/auditor_spec.rb index cff4044b..15ff2f77 100644 --- a/spec/audited/auditor_spec.rb +++ b/spec/audited/auditor_spec.rb @@ -1270,4 +1270,20 @@ def stub_global_max_audits(max_audits) }.to_not change(Audited::Audit, :count) end end + + describe "call audit multiple times" do + it "should update audit options" do + user = Models::ActiveRecord::UserOnlyName.create + user.update(password: "new password 1", name: "new name 1") + expect(user.audits.last.audited_changes.keys).to eq(%w[name]) + + user.class.class_eval do + audited only: :password + end + + user = Models::ActiveRecord::UserOnlyName.last + user.update(password: "new password 2", name: "new name 2") + expect(user.audits.last.audited_changes.keys).to eq(%w[password]) + end + end end diff --git a/spec/support/active_record/models.rb b/spec/support/active_record/models.rb index 34dde868..53b57863 100644 --- a/spec/support/active_record/models.rb +++ b/spec/support/active_record/models.rb @@ -36,6 +36,12 @@ class UserOnlyPassword < ::ActiveRecord::Base audited only: :password end + class UserOnlyName < ::ActiveRecord::Base + self.table_name = :users + attribute :non_column_attr if Rails.gem_version >= Gem::Version.new("5.1") + audited only: :name + end + class UserRedactedPassword < ::ActiveRecord::Base self.table_name = :users audited redacted: :password