How can i create a state machine using on the fly using yaml configuration, where i can store and use multiple config files

53 views Asked by At

I have a requirement in my rails application to build a FSM and that FSM should be configurable. In my application i am creating a employee exit workflow that includes some processes needs to be completed before exit of an employee from an organization. And catch is each organization of the application should be able to store their own resignation configuration, for example which events should be triggered when this state transitioned. Their can be external events on which state can transition etc.

I tried aasm gem but i didn't found any feature that allows dynamically creating states

1

There are 1 answers

2
user3402754 On BEST ANSWER

Something along these lines should allow you use a yaml file in the appropriate model

include AASM

  
  def apply_custom_configuration(config_file_path)
    config = YAML.load_file(config_file_path)

    aasm do
      config['states'].each do |state|
        aasm_state state['name'].to_sym, initial: state['initial'] || false
      end

      config['events'].each do |event|
        aasm_event event['name'].to_sym do
          transitions from: event['from'].map(&:to_sym), to: event['to'].to_sym
        end
      end
    end
  end

Then something along these lines can be used where the actual employee exit is performed.

config_file_path = Rails.root.join('config', 'employee_exit_workflows', 'organization1.yaml')
employee_exit = EmployeeExit.new
employee_exit.apply_custom_configuration(config_file_path)

How about persisting the custom workflows in a database?

To persist the data in your database:

  1. Creates a custom_workflows model
  2. Serialise the YAML
  3. Load and save the YAML configuration

Here's a snippet for saving it to the database:

config = YAML.load_file('path_to_your_yaml_file.yaml')
custom_workflow = CustomWorkflow.new(organization: 'org_name', config: config)
custom_workflow.save

The snippet above assumes the new table has just two fields but you can modify it to suit your needs.

You can then retrieve a custom workflow thus:

workflows = CustomWorkflow.where(organization: 'org_name')