lib/audited/auditor.rb in audited-4.10.0 vs lib/audited/auditor.rb in audited-5.0.0
- old
+ new
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
module Audited
# Specify this act if you want changes to your model to be saved in an
# audit table. This assumes there is an audits table ready.
#
# class User < ActiveRecord::Base
@@ -62,11 +64,11 @@
extend Audited::Auditor::AuditedClassMethods
include Audited::Auditor::AuditedInstanceMethods
class_attribute :audit_associated_with, instance_writer: false
- class_attribute :audited_options, instance_writer: false
+ class_attribute :audited_options, instance_writer: false
attr_accessor :audit_version, :audit_comment
self.audited_options = options
normalize_audited_options
@@ -78,12 +80,12 @@
end
has_many :audits, -> { order(version: :asc) }, as: :auditable, class_name: Audited.audit_class.name, inverse_of: :auditable
Audited.audit_class.audited_class_names << to_s
- after_create :audit_create if audited_options[:on].include?(:create)
- before_update :audit_update if audited_options[:on].include?(:update)
+ after_create :audit_create if audited_options[:on].include?(:create)
+ before_update :audit_update if audited_options[:on].include?(:update)
before_destroy :audit_destroy if audited_options[:on].include?(:destroy)
# Define and set after_audit and around_audit callbacks. This might be useful if you want
# to notify a party after the audit has been created or if you want to access the newly-created
# audit.
@@ -98,12 +100,12 @@
has_many :associated_audits, as: :associated, class_name: Audited.audit_class.name
end
end
module AuditedInstanceMethods
- REDACTED = '[REDACTED]'
-
+ REDACTED = "[REDACTED]"
+
# Temporarily turns off auditing while saving.
def save_without_auditing
without_auditing { save }
end
@@ -140,11 +142,11 @@
# end
#
def revisions(from_version = 1)
return [] unless audits.from_version(from_version).exists?
- all_audits = audits.select([:audited_changes, :version]).to_a
+ all_audits = audits.select([:audited_changes, :version, :action]).to_a
targeted_audits = all_audits.select { |audit| audit.version >= from_version }
previous_attributes = reconstruct_attributes(all_audits - targeted_audits)
targeted_audits.map do |audit|
@@ -154,11 +156,11 @@
end
# Get a specific revision specified by the version number, or +:previous+
# Returns nil for versions greater than revisions count
def revision(version)
- if version == :previous || self.audits.last.version >= version
+ if version == :previous || audits.last.version >= version
revision_with Audited.audit_class.reconstruct_attributes(audits_to(version))
end
end
# Find the oldest revision recorded prior to the date/time provided.
@@ -174,13 +176,13 @@
end
# Returns a list combined of record audits and associated audits.
def own_and_associated_audits
Audited.audit_class.unscoped
- .where('(auditable_type = :type AND auditable_id = :id) OR (associated_type = :type AND associated_id = :id)',
- type: self.class.name, id: id)
- .order(created_at: :desc)
+ .where("(auditable_type = :type AND auditable_id = :id) OR (associated_type = :type AND associated_id = :id)",
+ type: self.class.base_class.name, id: id)
+ .order(created_at: :desc)
end
# Combine multiple audits into one.
def combine_audits(audits_to_combine)
combine_target = audits_to_combine.last
@@ -196,16 +198,16 @@
protected
def revision_with(attributes)
dup.tap do |revision|
revision.id = id
- revision.send :instance_variable_set, '@new_record', destroyed?
- revision.send :instance_variable_set, '@persisted', !destroyed?
- revision.send :instance_variable_set, '@readonly', false
- revision.send :instance_variable_set, '@destroyed', false
- revision.send :instance_variable_set, '@_destroyed', false
- revision.send :instance_variable_set, '@marked_for_destruction', false
+ revision.send :instance_variable_set, "@new_record", destroyed?
+ revision.send :instance_variable_set, "@persisted", !destroyed?
+ revision.send :instance_variable_set, "@readonly", false
+ revision.send :instance_variable_set, "@destroyed", false
+ revision.send :instance_variable_set, "@_destroyed", false
+ revision.send :instance_variable_set, "@marked_for_destruction", false
Audited.audit_class.assign_revision_attributes(revision, attributes)
# Remove any association proxies so that they will be recreated
# and reference the correct object for this revision. The only way
# to determine if an instance variable is a proxy object is to
@@ -235,16 +237,18 @@
filtered_changes = normalize_enum_changes(filtered_changes)
filtered_changes.to_hash
end
def normalize_enum_changes(changes)
+ return changes if Audited.store_synthesized_enums
+
self.class.defined_enums.each do |name, values|
if changes.has_key?(name)
changes[name] = \
if changes[name].is_a?(Array)
changes[name].map { |v| values[v] }
- elsif rails_below?('5.0')
+ elsif rails_below?("5.0")
changes[name]
else
values[changes[name]]
end
end
@@ -254,16 +258,16 @@
def redact_values(filtered_changes)
[audited_options[:redacted]].flatten.compact.each do |option|
changes = filtered_changes[option.to_s]
new_value = audited_options[:redaction_value] || REDACTED
- if changes.is_a? Array
- values = changes.map { new_value }
+ values = if changes.is_a? Array
+ changes.map { new_value }
else
- values = new_value
+ new_value
end
- hash = Hash[option.to_s, values]
+ hash = {option.to_s => values}
filtered_changes.merge!(hash)
end
filtered_changes
end
@@ -272,60 +276,63 @@
Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new(rails_version)
end
def audits_to(version = nil)
if version == :previous
- version = if self.audit_version
- self.audit_version - 1
- else
- previous = audits.descending.offset(1).first
- previous ? previous.version : 1
- end
+ version = if audit_version
+ audit_version - 1
+ else
+ previous = audits.descending.offset(1).first
+ previous ? previous.version : 1
+ end
end
audits.to_version(version)
end
def audit_create
- write_audit(action: 'create', audited_changes: audited_attributes,
+ write_audit(action: "create", audited_changes: audited_attributes,
comment: audit_comment)
end
def audit_update
unless (changes = audited_changes).empty? && (audit_comment.blank? || audited_options[:update_with_comment_only] == false)
- write_audit(action: 'update', audited_changes: changes,
+ write_audit(action: "update", audited_changes: changes,
comment: audit_comment)
end
end
def audit_destroy
- write_audit(action: 'destroy', audited_changes: audited_attributes,
- comment: audit_comment) unless new_record?
+ unless new_record?
+ write_audit(action: "destroy", audited_changes: audited_attributes,
+ comment: audit_comment)
+ end
end
def write_audit(attrs)
attrs[:associated] = send(audit_associated_with) unless audit_associated_with.nil?
self.audit_comment = nil
if auditing_enabled
run_callbacks(:audit) {
audit = audits.create(attrs)
- combine_audits_if_needed if attrs[:action] != 'create'
+ combine_audits_if_needed if attrs[:action] != "create"
audit
}
end
end
def presence_of_audit_comment
if comment_required_state?
- errors.add(:audit_comment, "Comment can't be blank!") unless audit_comment.present?
+ errors.add(:audit_comment, :blank) unless audit_comment.present?
end
end
def comment_required_state?
auditing_enabled &&
- ((audited_options[:on].include?(:create) && self.new_record?) ||
- (audited_options[:on].include?(:update) && self.persisted? && self.changed?))
+ audited_changes.present? &&
+ ((audited_options[:on].include?(:create) && new_record?) ||
+ (audited_options[:on].include?(:update) && persisted? && changed?))
end
def combine_audits_if_needed
max_audits = audited_options[:max_audits]
if max_audits && (extra_count = audits.count - max_audits) > 0
@@ -334,22 +341,21 @@
end
end
def require_comment
if auditing_enabled && audit_comment.blank?
- errors.add(:audit_comment, "Comment can't be blank!")
- return false if Rails.version.start_with?('4.')
+ errors.add(:audit_comment, :blank)
throw(:abort)
end
end
CALLBACKS.each do |attr_name|
alias_method "#{attr_name}_callback".to_sym, attr_name
end
def auditing_enabled
- return run_conditional_check(audited_options[:if]) &&
+ run_conditional_check(audited_options[:if]) &&
run_conditional_check(audited_options[:unless], matching: false) &&
self.class.auditing_enabled
end
def run_conditional_check(condition, matching: true)
@@ -363,10 +369,10 @@
def reconstruct_attributes(audits)
attributes = {}
audits.each { |audit| attributes.merge!(audit.new_attributes) }
attributes
end
- end # InstanceMethods
+ end
module AuditedClassMethods
# Returns an array of columns that are audited. See non_audited_columns
def audited_columns
@audited_columns ||= column_names - non_audited_columns