module AASM::Persistence::ORM

def aasm_execute_after_commit

def aasm_execute_after_commit
  yield
end

def aasm_fire_event(state_machine_name, name, options, *args, &block)

Returns true if event was fired successfully and transaction completed.
def aasm_fire_event(state_machine_name, name, options, *args, &block)
  return super unless aasm_supports_transactions? && options[:persist]
  event = self.class.aasm(state_machine_name).state_machine.events[name]
  event.fire_callbacks(:before_transaction, self, *args)
  event.fire_global_callbacks(:before_all_transactions, self, *args)
  begin
    success = if options[:persist] && use_transactions?(state_machine_name)
      aasm_transaction(requires_new?(state_machine_name), requires_lock?(state_machine_name)) do
        super
      end
    else
      super
    end
    if success && !(event.options.keys & [:after_commit, :after_all_commits]).empty?
      aasm_execute_after_commit do
        event.fire_callbacks(:after_commit, self, *args)
        event.fire_global_callbacks(:after_all_commits, self, *args)
      end
    end
    success
  ensure
    event.fire_callbacks(:after_transaction, self, *args)
    event.fire_global_callbacks(:after_all_transactions, self, *args)
  end
end

def aasm_raise_invalid_record

def aasm_raise_invalid_record
  raise("Define #aasm_raise_invalid_record in the AASM Persistence class.")
end

def aasm_raw_attribute_value(state, _name=:default)

def aasm_raw_attribute_value(state, _name=:default)
  state.to_s
end

def aasm_read_attribute(name)

def aasm_read_attribute(name)
  raise("Define #aasm_read_attribute the AASM Persistence class.")
end

def aasm_rollback(name, old_value)

def aasm_rollback(name, old_value)
  aasm_write_attribute(self.class.aasm(name).attribute_name, old_value)
  false
end

def aasm_save

Save the record and return true if it succeeded/false otherwise.
def aasm_save
  raise("Define #aasm_save_without_error in the AASM Persistence class.")
end

def aasm_skipping_validations(state_machine_name)

def aasm_skipping_validations(state_machine_name)
  AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.skip_validation_on_save
end

def aasm_supports_transactions?

def aasm_supports_transactions?
  true
end

def aasm_transaction(requires_new, requires_lock)

Returns true or false if transaction completed successfully.
def aasm_transaction(requires_new, requires_lock)
  raise("Define #aasm_transaction the AASM Persistence class.")
end

def aasm_update_column(attribute_name, value)

Update only the column without running validations.
def aasm_update_column(attribute_name, value)
  raise("Define #aasm_update_column in the AASM Persistence class.")
end

def aasm_whiny_persistence(state_machine_name)

def aasm_whiny_persistence(state_machine_name)
  AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.whiny_persistence
end

def aasm_write_attribute(name, value)

def aasm_write_attribute(name, value)
  raise("Define #aasm_write_attribute in the AASM Persistence class.")
end

def aasm_write_state(state, name=:default)

NOTE: intended to be called from an event

Foo.find(1).aasm.current_state # => :closed
foo.aasm.current_state # => :closed
foo.close!
foo.aasm.current_state # => :opened
foo = Foo.find(1)

Writes state to the state column and persists it to the database
def aasm_write_state(state, name=:default)
  attribute_name = self.class.aasm(name).attribute_name
  old_value = aasm_read_attribute(attribute_name)
  aasm_write_state_attribute state, name
  success = if aasm_skipping_validations(name)
    aasm_update_column(attribute_name, aasm_raw_attribute_value(state, name))
  else
    aasm_save
  end
  unless success
    aasm_rollback(name, old_value)
    aasm_raise_invalid_record if aasm_whiny_persistence(name)
  end
  success
end

def aasm_write_state_attribute(state, name=:default)

def aasm_write_state_attribute(state, name=:default)
  aasm_write_attribute(self.class.aasm(name).attribute_name, aasm_raw_attribute_value(state, name))
end

def aasm_write_state_without_persistence(state, name=:default)

NOTE: intended to be called from an event

Foo.find(1).aasm.current_state # => :closed
foo.aasm.current_state # => :closed
foo.save
Foo.find(1).aasm.current_state # => :opened
foo.aasm.current_state # => :closed
foo.close
foo.aasm.current_state # => :opened
foo = Foo.find(1)

Writes state to the state field, but does not persist it to the database
def aasm_write_state_without_persistence(state, name=:default)
  aasm_write_state_attribute(state, name)
end

def requires_lock?(state_machine_name)

def requires_lock?(state_machine_name)
  AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.requires_lock
end

def requires_new?(state_machine_name)

def requires_new?(state_machine_name)
  AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.requires_new_transaction
end

def use_transactions?(state_machine_name)

def use_transactions?(state_machine_name)
  AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.use_transactions
end