mirror of
https://github.com/aasm/aasm
synced 2023-03-27 23:22:41 -04:00
started to refactor instance methods for AASM objects
This commit is contained in:
parent
d88fa9f2bc
commit
f66f2a1e76
5 changed files with 88 additions and 56 deletions
|
@ -4,6 +4,7 @@ require 'ostruct'
|
||||||
require File.join(File.dirname(__FILE__), 'aasm', 'version')
|
require File.join(File.dirname(__FILE__), 'aasm', 'version')
|
||||||
require File.join(File.dirname(__FILE__), 'aasm', 'errors')
|
require File.join(File.dirname(__FILE__), 'aasm', 'errors')
|
||||||
require File.join(File.dirname(__FILE__), 'aasm', 'base')
|
require File.join(File.dirname(__FILE__), 'aasm', 'base')
|
||||||
|
require File.join(File.dirname(__FILE__), 'aasm', 'instance_base')
|
||||||
require File.join(File.dirname(__FILE__), 'aasm', 'transition')
|
require File.join(File.dirname(__FILE__), 'aasm', 'transition')
|
||||||
require File.join(File.dirname(__FILE__), 'aasm', 'event')
|
require File.join(File.dirname(__FILE__), 'aasm', 'event')
|
||||||
require File.join(File.dirname(__FILE__), 'aasm', 'state')
|
require File.join(File.dirname(__FILE__), 'aasm', 'state')
|
||||||
|
|
|
@ -77,96 +77,70 @@ module AASM
|
||||||
end
|
end
|
||||||
end # ClassMethods
|
end # ClassMethods
|
||||||
|
|
||||||
# this method does what? does it deliver the current state?
|
def aasm
|
||||||
def aasm_current_state
|
@aasm ||= AASM::InstanceBase.new(self)
|
||||||
@aasm_current_state ||=
|
end
|
||||||
aasm_persistable? ? aasm_read_state : aasm_enter_initial_state
|
|
||||||
|
# deprecated
|
||||||
|
def aasm_current_state
|
||||||
|
# warn "#aasm_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.state instead!"
|
||||||
|
aasm.current_state
|
||||||
end
|
end
|
||||||
|
|
||||||
# private?
|
|
||||||
def aasm_enter_initial_state
|
def aasm_enter_initial_state
|
||||||
state_name = aasm_determine_state_name(self.class.aasm_initial_state)
|
state_name = aasm.determine_state_name(self.class.aasm_initial_state)
|
||||||
state = aasm_state_object_for_state(state_name)
|
state = aasm.state_object_for_name(state_name)
|
||||||
|
|
||||||
state.fire_callbacks(:before_enter, self)
|
state.fire_callbacks(:before_enter, self)
|
||||||
state.fire_callbacks(:enter, self)
|
state.fire_callbacks(:enter, self)
|
||||||
self.aasm_current_state = state_name
|
aasm.current_state = state_name
|
||||||
state.fire_callbacks(:after_enter, self)
|
state.fire_callbacks(:after_enter, self)
|
||||||
|
|
||||||
state_name
|
state_name
|
||||||
end
|
end
|
||||||
|
|
||||||
# private?
|
# deprecated
|
||||||
def aasm_events_for_current_state
|
def aasm_events_for_current_state
|
||||||
aasm_events_for_state(aasm_current_state)
|
# warn "#aasm_events_for_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.events instead!"
|
||||||
|
aasm.events(aasm.current_state)
|
||||||
end
|
end
|
||||||
|
|
||||||
# filters the results of events_for_current_state so that only those that
|
# filters the results of events_for_current_state so that only those that
|
||||||
# are really currently possible (given transition guards) are shown.
|
# are really currently possible (given transition guards) are shown.
|
||||||
def aasm_permissible_events_for_current_state
|
def aasm_permissible_events_for_current_state
|
||||||
aasm_events_for_current_state.select{ |e| self.send(("may_" + e.to_s + "?").to_sym) }
|
aasm.events(aasm.current_state).select{ |e| self.send(("may_" + e.to_s + "?").to_sym) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def aasm_events_for_state(state)
|
# deprecated
|
||||||
events = self.class.aasm_events.values.select {|event| event.transitions_from_state?(state) }
|
def aasm_events_for_state(state_name)
|
||||||
events.map {|event| event.name}
|
# warn "#aasm_events_for_state(state_name) is deprecated and will be removed in version 3.2.0; please use #aasm.events(state_name) instead!"
|
||||||
|
aasm.events(state_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# deprecated
|
||||||
def aasm_human_state
|
def aasm_human_state
|
||||||
AASM::Localizer.new.human_state_name(self.class, aasm_current_state)
|
# warn "#aasm_human_state is deprecated and will be removed in version 3.2.0; please use #aasm.human_state instead!"
|
||||||
|
aasm.human_state
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def aasm_persistable?
|
|
||||||
self.respond_to?(:aasm_read_state) || self.private_methods.include?('aasm_read_state')
|
|
||||||
end
|
|
||||||
|
|
||||||
def aasm_set_current_state_with_persistence(state)
|
def aasm_set_current_state_with_persistence(state)
|
||||||
save_success = true
|
save_success = true
|
||||||
if self.respond_to?(:aasm_write_state) || self.private_methods.include?('aasm_write_state')
|
if self.respond_to?(:aasm_write_state) || self.private_methods.include?('aasm_write_state')
|
||||||
save_success = aasm_write_state(state)
|
save_success = aasm_write_state(state)
|
||||||
end
|
end
|
||||||
self.aasm_current_state = state if save_success
|
aasm.current_state = state if save_success
|
||||||
|
|
||||||
save_success
|
save_success
|
||||||
end
|
end
|
||||||
|
|
||||||
def aasm_current_state=(state)
|
|
||||||
if self.respond_to?(:aasm_write_state_without_persistence) || self.private_methods.include?('aasm_write_state_without_persistence')
|
|
||||||
aasm_write_state_without_persistence(state)
|
|
||||||
end
|
|
||||||
@aasm_current_state = state
|
|
||||||
end
|
|
||||||
|
|
||||||
def aasm_determine_state_name(state)
|
|
||||||
case state
|
|
||||||
when Symbol, String
|
|
||||||
state
|
|
||||||
when Proc
|
|
||||||
state.call(self)
|
|
||||||
else
|
|
||||||
raise NotImplementedError, "Unrecognized state-type given. Expected Symbol, String, or Proc."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def aasm_state_object_for_state(name)
|
|
||||||
obj = self.class.aasm_states.find {|s| s == name}
|
|
||||||
raise AASM::UndefinedState, "State :#{name} doesn't exist" if obj.nil?
|
|
||||||
obj
|
|
||||||
end
|
|
||||||
|
|
||||||
def aasm_may_fire_event?(name, *args)
|
|
||||||
event = self.class.aasm_events[name]
|
|
||||||
event.may_fire?(self, *args)
|
|
||||||
end
|
|
||||||
|
|
||||||
def aasm_fire_event(name, options, *args)
|
def aasm_fire_event(name, options, *args)
|
||||||
persist = options[:persist]
|
persist = options[:persist]
|
||||||
|
|
||||||
event = self.class.aasm_events[name]
|
event = self.class.aasm_events[name]
|
||||||
begin
|
begin
|
||||||
old_state = aasm_state_object_for_state(aasm_current_state)
|
old_state = aasm.state_object_for_name(aasm.current_state)
|
||||||
|
|
||||||
|
|
||||||
old_state.fire_callbacks(:exit, self)
|
old_state.fire_callbacks(:exit, self)
|
||||||
|
@ -175,7 +149,7 @@ private
|
||||||
event.fire_callbacks(:before, self)
|
event.fire_callbacks(:before, self)
|
||||||
|
|
||||||
if new_state_name = event.fire(self, *args)
|
if new_state_name = event.fire(self, *args)
|
||||||
new_state = aasm_state_object_for_state(new_state_name)
|
new_state = aasm.state_object_for_name(new_state_name)
|
||||||
|
|
||||||
# new before_ callbacks
|
# new before_ callbacks
|
||||||
old_state.fire_callbacks(:before_exit, self)
|
old_state.fire_callbacks(:before_exit, self)
|
||||||
|
@ -188,7 +162,7 @@ private
|
||||||
persist_successful = aasm_set_current_state_with_persistence(new_state_name)
|
persist_successful = aasm_set_current_state_with_persistence(new_state_name)
|
||||||
event.fire_callbacks(:success, self) if persist_successful
|
event.fire_callbacks(:success, self) if persist_successful
|
||||||
else
|
else
|
||||||
self.aasm_current_state = new_state_name
|
aasm.current_state = new_state_name
|
||||||
end
|
end
|
||||||
|
|
||||||
if persist_successful
|
if persist_successful
|
||||||
|
@ -196,7 +170,7 @@ private
|
||||||
new_state.fire_callbacks(:after_enter, self)
|
new_state.fire_callbacks(:after_enter, self)
|
||||||
event.fire_callbacks(:after, self)
|
event.fire_callbacks(:after, self)
|
||||||
|
|
||||||
self.aasm_event_fired(name, old_state.name, self.aasm_current_state) if self.respond_to?(:aasm_event_fired)
|
self.aasm_event_fired(name, old_state.name, aasm.current_state) if self.respond_to?(:aasm_event_fired)
|
||||||
else
|
else
|
||||||
self.aasm_event_failed(name, old_state.name) if self.respond_to?(:aasm_event_failed)
|
self.aasm_event_failed(name, old_state.name) if self.respond_to?(:aasm_event_failed)
|
||||||
end
|
end
|
||||||
|
@ -209,7 +183,7 @@ private
|
||||||
end
|
end
|
||||||
|
|
||||||
if AASM::StateMachine[self.class].config.whiny_transitions
|
if AASM::StateMachine[self.class].config.whiny_transitions
|
||||||
raise AASM::InvalidTransition, "Event '#{event.name}' cannot transition from '#{self.aasm_current_state}'"
|
raise AASM::InvalidTransition, "Event '#{event.name}' cannot transition from '#{aasm.current_state}'"
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,7 +46,7 @@ module AASM
|
||||||
# may_event? and get back a boolean that tells you whether the guard method
|
# may_event? and get back a boolean that tells you whether the guard method
|
||||||
# on the transition will let this happen.
|
# on the transition will let this happen.
|
||||||
@clazz.send(:define_method, "may_#{name.to_s}?") do |*args|
|
@clazz.send(:define_method, "may_#{name.to_s}?") do |*args|
|
||||||
aasm_may_fire_event?(name, *args)
|
aasm.may_fire_event?(name, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
@clazz.send(:define_method, "#{name.to_s}!") do |*args|
|
@clazz.send(:define_method, "#{name.to_s}!") do |*args|
|
||||||
|
|
57
lib/aasm/instance_base.rb
Normal file
57
lib/aasm/instance_base.rb
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
module AASM
|
||||||
|
class InstanceBase
|
||||||
|
|
||||||
|
def initialize(instance)
|
||||||
|
@instance = instance
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_state
|
||||||
|
@current_state ||= persistable? ? @instance.aasm_read_state : @instance.aasm_enter_initial_state
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_state=(state)
|
||||||
|
if @instance.respond_to?(:aasm_write_state_without_persistence) || @instance.private_methods.include?('aasm_write_state_without_persistence')
|
||||||
|
@instance.aasm_write_state_without_persistence(state)
|
||||||
|
end
|
||||||
|
@current_state = state
|
||||||
|
end
|
||||||
|
|
||||||
|
def human_state
|
||||||
|
AASM::Localizer.new.human_state_name(@instance.class, current_state)
|
||||||
|
end
|
||||||
|
|
||||||
|
def events(state=current_state)
|
||||||
|
events = @instance.class.aasm_events.values.select {|e| e.transitions_from_state?(state) }
|
||||||
|
events.map {|e| e.name}
|
||||||
|
end
|
||||||
|
|
||||||
|
def state_object_for_name(name)
|
||||||
|
obj = @instance.class.aasm.states.find {|s| s == name}
|
||||||
|
raise AASM::UndefinedState, "State :#{name} doesn't exist" if obj.nil?
|
||||||
|
obj
|
||||||
|
end
|
||||||
|
|
||||||
|
def determine_state_name(state)
|
||||||
|
case state
|
||||||
|
when Symbol, String
|
||||||
|
state
|
||||||
|
when Proc
|
||||||
|
state.call(@instance)
|
||||||
|
else
|
||||||
|
raise NotImplementedError, "Unrecognized state-type given. Expected Symbol, String, or Proc."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def may_fire_event?(name, *args)
|
||||||
|
event = @instance.class.aasm.events[name]
|
||||||
|
event.may_fire?(@instance, *args)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def persistable?
|
||||||
|
@instance.respond_to?(:aasm_read_state) || @instance.private_methods.include?('aasm_read_state')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -29,7 +29,7 @@ module AASM
|
||||||
# This allows for nil aasm states - be sure to add validation to your model
|
# This allows for nil aasm states - be sure to add validation to your model
|
||||||
def aasm_read_state
|
def aasm_read_state
|
||||||
if new_record?
|
if new_record?
|
||||||
send(self.class.aasm_column).blank? ? aasm_determine_state_name(self.class.aasm_initial_state) : send(self.class.aasm_column).to_sym
|
send(self.class.aasm_column).blank? ? aasm.determine_state_name(self.class.aasm_initial_state) : send(self.class.aasm_column).to_sym
|
||||||
else
|
else
|
||||||
send(self.class.aasm_column).nil? ? nil : send(self.class.aasm_column).to_sym
|
send(self.class.aasm_column).nil? ? nil : send(self.class.aasm_column).to_sym
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue