8/03/2009

状態遷移機械を使ってARを制御(Rails2.3.2 + aasm)

目的:状態遷移機械機能を使って、RailsのARを制御する。



気をつけること。状態遷移機械機能は、ActiveRecordに対するモジュールの形で提供され、gemとして各ウェブアプリにインストールする。acts_as_state_machine(obsolete)とaasmの2つがあるが、前者は更新が止まっており、後者がよくつかわれているらしい。最新のrestful_authenticationプラグインでも、後者のaasmを推奨している


  1. gemインストール。

    sudo gem sources -a http://gems.github.com
    sudo gem install rubyist-aasm


  2. railsアプリにインクルードするには、config/environment.rbに次の記述が必要。

    config.gem "rubyist-aasm", :source => "http://gems.github.com", :lib => 'aasm'

    config.gemを入れておくと、他のホストに配備した時に`rake gem:install'でライブラリがインストールできる。
  3. aasmで状態管理をするモデルSampleを作る。Sampleの各オブジェクトに状態がつく。

    ./script/generate model Sample content:text state:string
    rake db:migrate

    stateという名の文字列型のカラムは、Sampleモデルで生成されたオブジェクトが持つ「状態」を格納しておくレジスタ。この状態保持レジスタは、モデルに入れておかないとaasmが動作しない。

  4. app/models/sample.rbを編集。

    class Sample < ActiveRecord::Base
    include AASM

    aasm_column :state
    aasm_initial_state :q

    aasm_state :q
    aasm_state :editing, :enter => :open_gui, :exit => :close_gui
    aasm_state :executing, :enter => :open_browser, :exit => :close_browser
    aasm_state :quit

    aasm_event(:go_exec, :success => :show_status)do
    transitions(:from => [:q, :editing],
    :to => :executing,
    :on_transition => :going_execution)
    end

    aasm_event(:go_edit,:success => :show_status)do
    transitions(:from => [:q, :executing],
    :to => :editing,
    :on_transition => :going_edition)
    end

    aasm_event(:quit_session, :success => :show_status)do
    transitions(:from => [:edititng, :executing],
    :to => :quit,
    :on_transition => :end_session)
    end

    def show_status
    puts "I'm in #{self.aasm_current_state}"
    end

    def open_gui
    puts 'GUI Editor opened.'
    end

    def close_gui
    puts 'GUI Edior closed.'
    end

    def open_browser
    puts 'Browser opened.'
    end

    def close_browser
    puts 'Browser closed.'
    end

    def going_execution
    puts "Now we're entering execution."
    end

    def going_edition
    puts "Now we're entering edition."
    end

    def end_session
    puts "Session end."
    end

    end

    いくつか


    • aasm_columnは状態を入れておくレジスタとして使うモデルのカラムをシンボルで指定。


    • 初期状態はaasm_initial_stateで指定するが、状態を宣言するaasm_stateでも初期状態を指定しておくこと。


    • メソッドが駆動するタイミングは、:exit, :on_transition, :enter, :successの順に決まる。


    • 「Obj.状態名?」で、それが今の状態かどうかが判断できる。状態遷移は「Obj.イベント名!」で起る。