diff --git a/lib/generators/statesman/templates/active_record_transition_model.rb.erb b/lib/generators/statesman/templates/active_record_transition_model.rb.erb index 38c80798..d25433d4 100644 --- a/lib/generators/statesman/templates/active_record_transition_model.rb.erb +++ b/lib/generators/statesman/templates/active_record_transition_model.rb.erb @@ -9,7 +9,7 @@ class <%= klass %> < <%= Statesman::Utils.rails_5_or_higher? ? 'ApplicationRecor # self.updated_timestamp_column = nil <%- unless Statesman::Utils.rails_4_or_higher? -%> - attr_accessible :to_state, :metadata, :sort_key + attr_accessible :from_state, :to_state, :metadata, :sort_key <%- end -%> belongs_to :<%= parent_name %><%= class_name_option %>, inverse_of: :<%= table_name %> diff --git a/lib/generators/statesman/templates/create_migration.rb.erb b/lib/generators/statesman/templates/create_migration.rb.erb index 3f902cbc..e7ec93f4 100644 --- a/lib/generators/statesman/templates/create_migration.rb.erb +++ b/lib/generators/statesman/templates/create_migration.rb.erb @@ -1,6 +1,7 @@ class Create<%= migration_class_name %> < ActiveRecord::Migration<%= "[#{ActiveRecord::Migration.current_version}]" if Statesman::Utils.rails_5_or_higher? %> def change create_table :<%= table_name %> do |t| + t.string :from_state, null: false t.string :to_state, null: false t.text :metadata<%= ", default: #{metadata_default_value}" unless mysql? %> t.integer :sort_key, null: false diff --git a/lib/generators/statesman/templates/update_migration.rb.erb b/lib/generators/statesman/templates/update_migration.rb.erb index 49024956..3efd97a7 100644 --- a/lib/generators/statesman/templates/update_migration.rb.erb +++ b/lib/generators/statesman/templates/update_migration.rb.erb @@ -1,5 +1,6 @@ class AddStatesmanTo<%= migration_class_name %> < ActiveRecord::Migration<%= "[#{ActiveRecord::Migration.current_version}]" if Statesman::Utils.rails_5_or_higher? %> def change + add_column :<%= table_name %>, :from_state, :string, null: false add_column :<%= table_name %>, :to_state, :string, null: false add_column :<%= table_name %>, :metadata, :text<%= ", default: #{metadata_default_value}" unless mysql? %> add_column :<%= table_name %>, :sort_key, :integer, null: false diff --git a/lib/statesman/adapters/active_record.rb b/lib/statesman/adapters/active_record.rb index 1ee46417..36d15b65 100644 --- a/lib/statesman/adapters/active_record.rb +++ b/lib/statesman/adapters/active_record.rb @@ -81,7 +81,7 @@ def reset def create_transition(from, to, metadata) transition = transitions_for_parent.build( - default_transition_attributes(to, metadata), + default_transition_attributes(from, to, metadata), ) transition_class.transaction(requires_new: true) do @@ -116,13 +116,19 @@ def create_transition(from, to, metadata) transition end - def default_transition_attributes(to, metadata) - { + def default_transition_attributes(from, to, metadata) + attributes = { to_state: to, sort_key: next_sort_key, metadata: metadata, most_recent: not_most_recent_value(db_cast: false), } + + if @transition_class.has_attribute?(:from_state) + attributes[:from_state] = from + end + + attributes end def add_after_commit_callback(from, to, transition) diff --git a/lib/statesman/adapters/active_record_transition.rb b/lib/statesman/adapters/active_record_transition.rb index c25eb03d..969408de 100644 --- a/lib/statesman/adapters/active_record_transition.rb +++ b/lib/statesman/adapters/active_record_transition.rb @@ -19,6 +19,12 @@ module ActiveRecordTransition class_attribute :updated_timestamp_column self.updated_timestamp_column = DEFAULT_UPDATED_TIMESTAMP_COLUMN end + + def from_state + if has_attribute?(:from_state) + self[:from_state] + end + end end end end diff --git a/lib/statesman/adapters/memory.rb b/lib/statesman/adapters/memory.rb index 349e4dca..c620abbb 100644 --- a/lib/statesman/adapters/memory.rb +++ b/lib/statesman/adapters/memory.rb @@ -20,7 +20,7 @@ def initialize(transition_class, parent_model, observer, _opts = {}) def create(from, to, metadata = {}) from = from.to_s to = to.to_s - transition = transition_class.new(to, next_sort_key, metadata) + transition = transition_class.new(from, to, next_sort_key, metadata) @observer.execute(:before, from, to, transition) @history << transition diff --git a/lib/statesman/adapters/memory_transition.rb b/lib/statesman/adapters/memory_transition.rb index 1dfb2f4d..3ed91f6e 100644 --- a/lib/statesman/adapters/memory_transition.rb +++ b/lib/statesman/adapters/memory_transition.rb @@ -5,13 +5,15 @@ module Adapters class MemoryTransition attr_accessor :created_at attr_accessor :updated_at + attr_accessor :from_state attr_accessor :to_state attr_accessor :sort_key attr_accessor :metadata - def initialize(to, sort_key, metadata = {}) + def initialize(from, to, sort_key, metadata = {}) @created_at = Time.now @updated_at = Time.now + @from_state = from @to_state = to @sort_key = sort_key @metadata = metadata diff --git a/spec/statesman/adapters/memory_transition_spec.rb b/spec/statesman/adapters/memory_transition_spec.rb index 731e8694..b5d932bf 100644 --- a/spec/statesman/adapters/memory_transition_spec.rb +++ b/spec/statesman/adapters/memory_transition_spec.rb @@ -4,10 +4,12 @@ describe Statesman::Adapters::MemoryTransition do describe "#initialize" do + let(:from) { :n } let(:to) { :y } let(:sort_key) { 0 } - let(:create) { described_class.new(to, sort_key) } + let(:create) { described_class.new(from, to, sort_key) } + specify { expect(create.from_state).to equal(from) } specify { expect(create.to_state).to equal(to) } specify { expect(create.created_at).to be_a(Time) } specify { expect(create.updated_at).to be_a(Time) } @@ -15,7 +17,7 @@ context "with metadata passed" do let(:metadata) { { some: :hash } } - let(:create) { described_class.new(to, sort_key, metadata) } + let(:create) { described_class.new(from, to, sort_key, metadata) } specify { expect(create.metadata).to eq(metadata) } end diff --git a/spec/support/active_record.rb b/spec/support/active_record.rb index a8c7dbc0..cbcba744 100644 --- a/spec/support/active_record.rb +++ b/spec/support/active_record.rb @@ -70,6 +70,7 @@ def change class CreateMyActiveRecordModelTransitionMigration < MIGRATION_CLASS def change create_table :my_active_record_model_transitions do |t| + t.string :from_state t.string :to_state t.integer :my_active_record_model_id t.integer :sort_key @@ -189,6 +190,7 @@ def change class CreateOtherActiveRecordModelTransitionMigration < MIGRATION_CLASS def change create_table :other_active_record_model_transitions do |t| + t.string :from_state t.string :to_state t.integer :other_active_record_model_id t.integer :sort_key @@ -284,6 +286,7 @@ def change class CreateNamespacedARModelTransitionMigration < MIGRATION_CLASS def change create_table :my_namespace_my_active_record_model_transitions do |t| + t.string :from_state t.string :to_state t.integer :my_active_record_model_id t.integer :sort_key