class StateMachines::AuditTrail::Backend

Public Class Methods

create_for(transition_class, owner_class, options = {}) click to toggle source

Creates an instance of the Backend class which does the actual persistence of transition state information.

- transition_class: the Class which holds the audit trail

To add a new ORM, implement something similar to lib/state_machines/audit_trail/backend/active_record.rb and return from here the appropriate object based on which ORM the transition_class is using

# File lib/state_machines/audit_trail/backend.rb, line 41
def self.create_for(transition_class, owner_class, options = {})
  if Object.const_defined?('ActiveRecord') && transition_class.ancestors.include?(::ActiveRecord::Base)
    return StateMachines::AuditTrail::Backend::ActiveRecord.new(transition_class, owner_class, options)
  elsif Object.const_defined?('Mongoid') && transition_class.ancestors.include?(::Mongoid::Document)
    return StateMachines::AuditTrail::Backend::Mongoid.new(transition_class, owner_class, options)
  else
    raise 'Not implemented. Only support for ActiveRecord and Mongoid is implemented. Pull requests welcome.'
  end
end

Public Instance Methods

log(object, transition) click to toggle source

Resolve field values and persist

- object: the object being watched by the state_machines observer
- transition: state machine transition object that state machine passes to after/before transition callbacks
# File lib/state_machines/audit_trail/backend.rb, line 11
def log(object, transition)

  if transition.machine.presence
    # full transition object
    namespace = transition.machine.namespace
  else
    # initial state open struct
    namespace = transition.namespace
  end
  fields = {namespace: namespace, event: transition.event ? transition.event.to_s : nil, from: transition.from, to: transition.to}
  [*options[:context]].each { |field|
    fields[field] = resolve_context(object, field, transition)
  }

  # begin
  persist(object, fields)
  # rescue => e
  #   puts "\nUncaught #{e.class} persisting audit_trail: #{e.message}"
  #   puts "\t" + e.backtrace.join($/ + "\t")
  #   raise e
  # end
end
new_record?(object) click to toggle source

Exists in case ORM layer has a different way of answering this question, but works for most.

# File lib/state_machines/audit_trail/backend.rb, line 52
def new_record?(object)
  object.new_record?
end

Protected Instance Methods

persist(object, fields) click to toggle source
# File lib/state_machines/audit_trail/backend.rb, line 58
def persist(object, fields)
  raise 'Not implemented. Implement in a subclass.'
end
resolve_context(object, context, transition) click to toggle source
# File lib/state_machines/audit_trail/backend.rb, line 62
def resolve_context(object, context, transition)
  # ---------------
  # TODO: remove this check after we set a minimum version of Rails/ActiveRecord to 5.1+. At that time, the argument will be removed and the arity check will be enough. - rosskevin
  # Don't send params to Rails 5+ associations because it triggers a ton of deprecation messages.
  # @see https://github.com/state-machines/state_machines-audit_trail/issues/6
  #  check if activerecord && the context is an association
  skip_args = object.is_a?(::ActiveRecord::Base) && object.class.reflections.keys.include?(context.to_s)
  # ---------------

  if object.method(context).arity != 0 && !skip_args
    object.send(context, transition)
  else
    object.send(context)
  end
end