Class: Statecraft::Generators::FromStatesmanGenerator
- Inherits:
-
Rails::Generators::NamedBase
- Object
- Rails::Generators::NamedBase
- Statecraft::Generators::FromStatesmanGenerator
- Includes:
- ActiveRecord::Generators::Migration
- Defined in:
- lib/generators/statecraft/from_statesman/from_statesman_generator.rb
Overview
rails generate statecraft:from_statesman Order [OrderStateMachine] —
the migration path off statesman. Reads the live statesman machine
through reflection (states, initial state, transition graph, guard
locations), generates the in-place conversion migration that turns the
statesman transitions table into this gem's log, a machine skeleton
whose events and guards are left for the human, and mounts the machine
into the model. The statesman class itself is never loaded by name
magic beyond the optional second argument's default.
Instance Method Summary collapse
- #create_application_machine ⇒ Object
-
#create_conversion_migrations ⇒ Object
Three migrations, strong-migrations style: instant DDL, a batched backfill outside any DDL transaction, and a short-lock finalize.
- #create_machine_skeleton ⇒ Object
- #load_statesman_machine ⇒ Object
- #mount_model ⇒ Object
- #print_cleanup_instructions ⇒ Object
Instance Method Details
#create_application_machine ⇒ Object
33 34 35 36 37 38 |
# File 'lib/generators/statecraft/from_statesman/from_statesman_generator.rb', line 33 def create_application_machine application_machine_path = "app/state_machines/application_machine.rb" return if File.exist?(File.join(destination_root, application_machine_path)) template "application_machine.rb.tt", application_machine_path end |
#create_conversion_migrations ⇒ Object
Three migrations, strong-migrations style: instant DDL, a batched backfill outside any DDL transaction, and a short-lock finalize. migration_template numbers them monotonically, so they run in order.
56 57 58 59 60 61 62 63 |
# File 'lib/generators/statecraft/from_statesman/from_statesman_generator.rb', line 56 def create_conversion_migrations migration_template "convert_transitions_ddl.rb.tt", "#{migration_directory}/convert_#{migration_slug}_transitions_ddl.rb" migration_template "convert_transitions_backfill.rb.tt", "#{migration_directory}/convert_#{migration_slug}_transitions_backfill.rb" migration_template "convert_transitions_finalize.rb.tt", "#{migration_directory}/convert_#{migration_slug}_transitions_finalize.rb" end |
#create_machine_skeleton ⇒ Object
40 41 42 |
# File 'lib/generators/statecraft/from_statesman/from_statesman_generator.rb', line 40 def create_machine_skeleton template "machine_from_statesman.rb.tt", "app/state_machines/#{file_path}_flow.rb" end |
#load_statesman_machine ⇒ Object
24 25 26 27 28 29 30 31 |
# File 'lib/generators/statecraft/from_statesman/from_statesman_generator.rb', line 24 def load_statesman_machine @statesman_machine = resolve_statesman_machine @initial_state = @statesman_machine.initial_state return unless @initial_state.nil? raise Thor::Error, "#{statesman_class_name} declares no initial state; " \ "statecraft requires exactly one — declare `state ..., initial: true` first" end |
#mount_model ⇒ Object
44 45 46 47 48 49 50 51 |
# File 'lib/generators/statecraft/from_statesman/from_statesman_generator.rb', line 44 def mount_model unless File.exist?(File.join(destination_root, model_file)) say_status :skip, "#{model_file} not found — mount the machine yourself: #{mounting_line.strip}", :yellow return end inject_into_class model_file, class_name, mounting_line end |
#print_cleanup_instructions ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/generators/statecraft/from_statesman/from_statesman_generator.rb', line 65 def print_cleanup_instructions say "\nThe conversion is three migrations — run them per the README runbook:", :green say " 1. _ddl now (instant); 2. _backfill any time (batched, no long locks;" say " rerun it to catch up rows statesman wrote in between);" say " 3. _finalize after switching the code to statecraft." say "\nAfter finalize, finish the move by hand:", :green say " * #{log_class_name}: drop `include Statesman::Adapters::ActiveRecordTransition` and" say " the `after_destroy :update_most_recent` callback (they read dropped columns);" say " consider adding `def readonly? = persisted?` — the pipeline inserts around it." say " * #{class_name}: drop `include Statesman::Adapters::ActiveRecordQueries` and the" say " state_machine/transition helper methods that wrapped statesman." say " * Delete the `Statesman.configure` initializer once no machine is left." say " * Name your events in app/state_machines/#{file_path}_flow.rb — statesman had none." end |