require 'set' require 'audited/audit' module Audited module Adapters module ActiveRecord # Audit saves the changes to ActiveRecord models. It has the following attributes: # # * auditable: the ActiveRecord model that was changed # * user: the user that performed the change; a string or an ActiveRecord model # * action: one of create, update, or delete # * audited_changes: a serialized hash of all the changes # * comment: a comment set with the audit # * version: the version of the model # * request_uuid: a uuid based that allows audits from the same controller request # * created_at: Time that the change was performed # class Audit < ::ActiveRecord::Base include Audited::Audit include ActiveModel::Observing serialize :audited_changes default_scope ->{ order(:version)} scope :descending, ->{ reorder("version DESC")} scope :creates, ->{ where({:action => 'create'})} scope :updates, ->{ where({:action => 'update'})} scope :destroys, ->{ where({:action => 'destroy'})} scope :up_until, ->(date_or_time){where("created_at <= ?", date_or_time) } scope :from_version, ->(version){where(['version >= ?', version]) } scope :to_version, ->(version){where(['version <= ?', version]) } scope :auditable_finder, ->(auditable_id, auditable_type){where(auditable_id: auditable_id, auditable_type: auditable_type)} # Return all audits older than the current one. def ancestors self.class.where(['auditable_id = ? and auditable_type = ? and version <= ?', auditable_id, auditable_type, version]) end # Allows user to be set to either a string or an ActiveRecord object # @private def user_as_string=(user) # reset both either way self.user_as_model = self.username = nil user.is_a?(::ActiveRecord::Base) ? self.user_as_model = user : self.username = user end alias_method :user_as_model=, :user= alias_method :user=, :user_as_string= # @private def user_as_string self.user_as_model || self.username end alias_method :user_as_model, :user alias_method :user, :user_as_string private def set_version_number max = self.class.auditable_finder(auditable_id, auditable_type).maximum(:version) || 0 self.version = max + 1 end end end end end