Giới thiệu và sử dụng Gem State machine

I. State là gì?

State là trạng thái của hệ thống thực hiện một transaction( một transaction là tập hợp một nhóm các hành  động được thực thi khi điều kiện được thỏa mãn.

Ví dụ

state

(Nguồn wikimedia.org)

Bên trên là ví dụ về hệ thống cửa gồm 2 trạng thái opened và closed, và chúng phải qua các transaction để chuyển thành các trạng thái khác nhau

II. gem state_machine

1. giới thiệu

state_machine dùng để quản lý thuộc tính của đối tượng ( thuộc tính đó có nhiều trạng thái khác nhau)

Giả sử khi không dùng gem ta phải viết code

    class Order < ActiveRecord::Base

        attr_accessor :invalid_payment
        attr_accessible :purchase_at, :shiped_at, :cancel_at

        def self.open_oders?
            where('....')
        end

        def open?
            purchase_at; && !shiped_at             && !cancel_at
        end

        def purchase
        end

        def cancel
        end

        def resume
        end

        def ship
        end
end

Nhưng khi dùng gem mọi việc trở nên rõ ràng hơn, nhìn code cũng clear hơn

class Order < ActiveRecord::Base

    scope :open_orders, -> {with_state(:open)}

    attr_accessor :invalid_payment

    state_machine :state, initial: :incomplete do
        event :purchase do
            transition :incomplete => :open
        end

        event :cancel do
            transition :open => :canceled
        end

        event :resume do
            transition :canceled => :open
        end

        event :ship do
            transition :open => :shipped
        end

        before_transition :incomplete => :open do |order|
            !order.invalid_payment
        end
    end
end

2. các thành phần state_machine

Trong state_machine có rất nhiều thành phần dưới đây là một số thành phần cơ bản, chi tiết xem link tham khảo ở cuối trang

  • state : Trạng thái của đối tượng
  • events: StateMachine::Event < Object (được kế thừa từ lớp Object) : Một event là một hành động mà nó chuyển trạng thái của đối tượng từ trạng thái này sang trạng thái khác

ví dụ:

state_machine :state, initial: :incomplete do
    event :purchase do
        transition :incomplete => :open
    end
end
  • state : Transition : thể hiện cho sự thay đổi trạng thái của đối tượng bao gôm start state và end state, được kế thừa từ lớp object
  • StateMachine::Transition < Object

ví dụ:

state_machine :state, initial: :incomplete do
    event :purchase do
        transition :incomplete => :open
    end
end
  • state : Callback : Móc nối đối tượng, cho phép kích hoạt logic trước, sau hay quanh một tập các transaction
state_machine :state, initial: :incomplete do
    before_transition :incomplete => :open do |order|
        !order.invalid_payment
    end
end

3. Integrations

  • ActiveModel classes : Hữu ích cho việc lưu trữ và thực thi ORM(Object relation mapping), hỗ trợ validate, dirty attribute tracking..

  • ActiveRecord models : Hỗ trợ database transaction, tự động lưu dữ liệu , named scoped, validate

  • DataMapper resources : Giống như ActiveRecord integration ngoài ra còn có Extlib-like callbacks

  • Mongoid models : Hỗ trợ lưu record, validate, các scopes cơ bản

  • MongoMapper models : Hỗ trợ lưu record, validate, các scopes cơ bản, callback

  • Sequel models : Giống như ActiveRecord integration hỗ trợ db transaction, tự động lưu record, name scoped, validate và callback

4. Setup

  • Install gem
gem 'state_machine'
gem 'ruby-graphviz', :require => 'graphviz'
  • Create a model
$ rails generate model Vehicle state:string
$ rake db:migrate

III. Nguồn tham khảo

https://github.com/pluginaweek/state_machine http://rdoc.info/github/pluginaweek/state_machine/master/frames wikimedia.org


All Rights Reserved