Upgrade to Pro — share decks privately, control downloads, hide ads and more …

STATESMAN

 STATESMAN

kbaba1001

May 15, 2015
Tweet

More Decks by kbaba1001

Other Decks in Technology

Transcript

  1. State Machine Class class TaskStateMachine include Statesman::Machine state :unstarted, initial:

    true state :started state :finished event :start do transition from: :unstarted, to: :started end event :finish do transition from: :started, to: :finished end end
  2. Model class Task < ActiveRecord::Base include Statesman::Adapters::ActiveRecordQueries has_many :task_transitions, inverse_of:

    :task delegate :current_state, :trigger!, :available_events, to: :state_machine def state_machine @state_machine ||= TaskStateMachine.new(self, transition_class: TaskTransition) end private def self.transition_class; TaskTransition end def self.initial_state; :unstarted end end
  3. Transition Model # create_table "task_transitions", force: true do |t| #

    t.string "to_state", null: false # t.text "metadata", default: "{}" # t.integer "sort_key", null: false # t.integer "task_id", null: false # t.boolean "most_recent", null: false # t.datetime "created_at" # t.datetime "updated_at" # end # class TaskTransition < ActiveRecord::Base include Statesman::Adapters::ActiveRecordTransition belongs_to :task, inverse_of: :task_transitions end
  4. 使い方 task = Task.first task.current_state # => "unstarted" task.trigger!(:start) #

    => true/exception task.current_state # => "started" task.available_events # => [:finish, :deliver] Task.in_state(:started) # => [#<Task id: "123">] Task.not_in_state(:unstarted) # => [#<Task id: "123">]
  5. after_createで作る class Task < ActiveRecord::Base has_many :task_transitions, inverse_of: :task after_create

    :create_transition! private def create_transition! task_transitions.create!( to_state: TaskStateMachine.initial_state, sort_key: 0, metadata: {} ) end end
  6. コードの改修 # migration add_column :tasks, :current_state, :string # Task Model

    enumerize :current_state, in: TaskStateMachine.states, default: TaskStateMachine.initial_state scope :in_state, ->(*states) { where(current_state: states) } scope :not_in_state, ->(*states) { where.not(current_state: states) } # State Machine Class (TaskStateMachine) after_transition do |task, transition| task.update_column(:current_state, transition.to_state) end