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