Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load workflow specification from YAML file? #92

Closed
abhas opened this issue Aug 17, 2013 · 8 comments
Closed

Load workflow specification from YAML file? #92

abhas opened this issue Aug 17, 2013 · 8 comments

Comments

@abhas
Copy link

abhas commented Aug 17, 2013

I'm trying to build a user extensible workflow. So I wanted to check if there are any plans on building functionality to load the workflow specification from a YAML file?

I would love to work on this myself if you could give some pointers on how to get started.

@geekq
Copy link
Owner

geekq commented Aug 19, 2013

A workflow is definied by a Specification object.

Normally it is created with workflow do ... end, but it should be also possible to create it on the fly by serializing/deserializing Workflow::Specification from yml file.

We will presumably have to separate the workflow method into 2 parts. Will refactor and get back...

@geekq
Copy link
Owner

geekq commented Aug 19, 2013

Just extracted the assign_workflow method 556f5a6

To do what you want to do please create Workflow::Specification in some way, e.g. from definition in yml file. Then call assign_workflow.

@abhas
Copy link
Author

abhas commented Aug 20, 2013

Thanks a lot, Vladimir. This really helps. I'll try this out and provide feedback to you.

geekq added a commit that referenced this issue Aug 26, 2013
…, s. also #92, #69

* works on both subclassing and dynamic workflow spec assignment
* solving problems caused by metaprogramming with even more metaprogramming ;-)
@geekq geekq mentioned this issue Aug 26, 2013
@geekq geekq closed this as completed Jul 24, 2014
@mvaragnat
Copy link

Hello @geekq I see this old issue, matching my exact business need
Has it been closed because already implemented, or because it was too complicated / out of scope ? If so, do you have a workaround to suggest ?

@geekq
Copy link
Owner

geekq commented Oct 20, 2021

You need:

  1. to prepare a workflow specification object
  2. call assign_workflow

As explained in the 68951c9 example, you can load a specification object from yaml, then run assign_workflow https://github.com/geekq/workflow/blob/develop/lib/workflow.rb#L30

Or you maybe want to load your specially designed yaml and then call methods on the spec object like

mystates = [:foo, :bar, :baz] # here hard coded, but you can load from yaml file too
myspec = Workflow::Specification.new do
  mystates.each do |s| # iterate through the list loaded from yaml
    state s do
      event :foobalize, :transitions_to => :foo # we want each state to have a transition to :foo
    end
  end
end
myspec.states.length # you see you have 3 elements here - loaded from the array

The requirements on which workflow aspects, and how to be represented in yaml, may vary greatly. So they are better implemented in your application specific code.

@mvaragnat
Copy link

Thanks, very clear on the Specification part

My next question is where to call assign_workflow.

So let say I have a BusinessProcess model, intended to represent various workflows, each modelized in a yaml.
Can each instance of business_process can load a different yaml ?

class BusinessProcess < ApplicationRecord
  include Workflow
  
  assign_workflow load_spec_from_yaml(path: self.yaml_path)
  
  def load_spec_from_yaml(path:)
    states = Yaml.safe_load(path)
    return Workflow::Specification.new do
      # some magic inspired from your reply above
    end
  end
end

process1 = BusinessProcess.new(yaml_path: 'docs/myfile1.yaml')
process2 = BusinessProcess.new(yaml_path: 'docs/myfile2.yaml')

something like this ?

@geekq
Copy link
Owner

geekq commented Oct 20, 2021

I recommend https://www.manning.com/books/the-well-grounded-rubyist-second-edition book to learn about advanced, class level- and meta-programming.This is very good!

One user #55 (comment) also recommended http://ruby-metaprogramming.rubylearning.com/ (I have not read this one myself though)

For multiple workflows please also see the example https://github.com/geekq/workflow-activerecord/blob/develop/test/multiple_workflows_test.rb

# define workflow per object instead of per class

@tlloydthwaites
Copy link

tlloydthwaites commented Mar 7, 2024

This is pretty straight-forward, I achieved it like this:

c = Class.new
c.class_eval do
 include Workflow
end

hash = {
 state_1: {
   events: {
     event_1: {
       transition_to: :state_2,
       if: :event_1_condition?,
       meta: { e1: 1 }
     },
   },
   meta: { a: 1 }
 },
 state_2: {
   meta: { a: 2 }
 }
}

spec = Workflow::Specification.new {}

hash.each_pair do |state, state_def|
 spec.send :state, state, state_def
 state_def[:events]&.each_pair do |event, event_def|
   spec.send :event, event, event_def
 end
end

c.send :assign_workflow, spec

o = c.new
puts o.current_state
puts o.current_state.events

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants