La pregunta es, ¿las máquinas de estados siempre se definen estáticamente (en las clases)? ¿O hay una manera de que yo lo tenga así que cada instancia de la clase tiene su propio conjunto de estados?Dynamic State Machine en Ruby? ¿Las máquinas de estado deben ser clases?
Estoy revisando Stonepath para implementar un Motor de tareas. Realmente no veo la distinción entre "estados" y "tareas" allí, así que estoy pensando que podría asignar una tarea directamente a un estado. Esto permitiría que yo sea capaz de definir tareas listas (o flujos de trabajo) de forma dinámica, sin tener que hacer cosas como:
aasm_event :evaluate do
transitions :to => :in_evaluation, :from => :pending
end
aasm_event :accept do
transitions :to => :accepted, :from => :pending
end
aasm_event :reject do
transitions :to => :rejected, :from => :pending
end
En cambio, un WorkItem (el flujo de trabajo/tarea principal modelo manager), simplemente tendría muchos Tareas. A continuación, las tareas trabajarían como estados, por lo que podría hacer algo como esto:
aasm_initial_state :initial
tasks.each do |task|
aasm_state task.name.to_sym
end
previous_state = nil
tasks.each do |tasks|
aasm_event task.name.to_sym do
transitions :to => "#{task.name}_phase".to_sym, :from => previous_state ? "#{task.name}_phase" : "initial"
end
previous_state = state
end
Sin embargo, no puedo hacer eso con el aasm gem porque esos métodos (aasm_state
y aasm_event
) son métodos de clase, por lo que cada instancia de la clase con esa máquina de estados tiene los mismos estados. Lo quiero para que un "WorkItem" o "TaskList" dinámicamente cree una secuencia de estados y transiciones basadas en las tareas que tiene.
Esto me permitiría definir dinámicamente los flujos de trabajo y simplemente hacer que los estados se correlacionen con las tareas.
¿Alguna vez se han utilizado máquinas de estados como esta? Parece que este ruby workflow gem es similar a lo que estoy describiendo.
Actualización: Me veo haciendo algo como lo siguiente, pero parece tipo de hacker:
@implementation_state_machine = Class::new do
include AASM
aasm_initial_state :initial
tasks.each { |state| aasm_state :"#{task.name}"}
# ...
end
... donde una propiedad en mi modelo sería implementation_state_machine
. Tendría que anular method_missing
para delegar métodos relacionados con el estado (accepted_phase?
) a la clase anónima de implementación.