module StateMachines::Integrations::Mongoid

def self.locale_path

def self.locale_path
  "#{File.dirname(__FILE__)}/mongoid/locale.rb"
end

def self.matching_ancestors

Mongoid integration.
Classes that include Mongoid::Document will automatically use the
def self.matching_ancestors
  [::Mongoid::Document]
end

def around_save(object)

Runs state events around the machine's :save action
def around_save(object)
  object.class.state_machines.transitions(object, action).perform { yield }
end

def attribute_field

Gets the field for this machine's attribute (if it exists)
def attribute_field
  owner_class.fields[attribute.to_s] || owner_class.fields[owner_class.aliased_fields[attribute.to_s]]
end

def create_with_scope(name)

states for the attribute
Creates a scope for finding records *with* a particular state or
def create_with_scope(name)
  define_scope(name, lambda { |values| { attribute => { '$in' => values } } })
end

def create_without_scope(name)

states for the attribute
Creates a scope for finding records *without* a particular state or
def create_without_scope(name)
  define_scope(name, lambda { |values| { attribute => { '$nin' => values } } })
end

def define_action_hook

Uses around callbacks to run state events if using the :save hook
def define_action_hook
  if action_hook == :save
    define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
        def insert(*)
          self.class.state_machine(#{name.inspect}).send(:around_save, self) { super.persisted? }
          self
        end
        def update(*)
          self.class.state_machine(#{name.inspect}).send(:around_save, self) { super }
        end
        def update_document(*)
          self.class.state_machine(#{name.inspect}).send(:around_save, self) { super }
        end
        def upsert(*)
          self.class.state_machine(#{name.inspect}).send(:around_save, self) { super }
        end
    end_eval
  else
    super
  end
end

def define_scope(_name, scope)

Defines a new scope with the given name
def define_scope(_name, scope)
  lambda { |model, values| model.criteria.where(scope.call(values)) }
end

def define_state_accessor

Skips defining reader/writer methods since this is done automatically
def define_state_accessor
  owner_class.field(attribute, type: String) unless attribute_field
  super
end

def define_state_initializer

object
initial state of the machine *before* any attributes are set on the
Defines an initialization hook into the owner class for setting the
def define_state_initializer
  define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
      def initialize(*)
        super do |*args|
          self.class.state_machines.initialize_states(self, :static => false)
          yield(*args) if block_given?
        end
      end
      def apply_pre_processed_defaults
        defaults = {}
        self.class.state_machines.initialize_states(self, :static => :force, :dynamic => false, :to => defaults)
        defaults.each do |attr, value|
          send(:"\#{attr}=", value) unless attributes.include?(attr)
        end
        super
      end
  end_eval
end

def locale_path

def locale_path
  "#{File.dirname(__FILE__)}/mongoid/locale.rb"
end

def owner_class_attribute_default

Gets the db default for the machine's attribute
def owner_class_attribute_default
  attribute_field && attribute_field.default_val
end

def runs_validations_on_action?

Only runs validations on the action if using :save
def runs_validations_on_action?
  action == :save
end