1

私は、レール 4 でキックスターターインディーゴゴに似た e コマース プラットフォームを作成しています。商品がどのような状態になるかは、注文が十分にあるかどうかなど、さまざまな条件によって大きく異なります。たとえば、gem を使用する場合state_machine、コードは次のようになります。

class Product  < ActiveRecord::Base
  has_many :orders

  state_machine :initial => :prelaunch do
    event :launch do
      transition :prelaunch => :pending, :if => lambda {|p| p.launch_at <= Time.now }
    end

    event :fund do
      transition :pending => :funded, :if => :has_enough_orders?
    end
  end

  def has_enough_orders?
    if orders.count > 10
  end
end

次に、おそらくモデル オブザーバーを作成して、注文が行われるたびに確認product.has_enough_orders?し、それが返された場合はtrueを呼び出すようにしますproduct.fund!。そのhas_enough_orders?ため、何度もチェックされています。それはあまり効率的ではないようです。

さらにproduct.launch!、同様の問題があります。それを実装するために私が考えることができる最善の方法は、次のようなものを使用しsidekiqて、事前に発売された製品がlaunch_at時間を過ぎたかどうかを確認する仕事をすることです. ただし、これも同様に汚いようです。

考えすぎですか、それともこれが通常のステート マシンの使用方法ですか?

4

1 に答える 1

5

状態をより適切に処理できるように、ステート マシンを変更しました。

after_transitionまたはbefore_transitionメソッドを使用できます

class Product < ActiveRecord::Base
  has_many :orders

  state_machine :initial => :prelaunch do
    after_transition :prelaunch, :do => :check_launch
    after_transition :pending, :do => :has_enough_orders?

    event :launch do
      transition :prelaunch => :pending
    end

    event :fund do
      transition :pending => :funded
    end
  end

  def check_launch
    if launch_at <= Time.now
      self.launch # call event :launch
    else
      # whatever you want
    end
  end

  def has_enough_orders?
    if orders.count > 10
      self.fund # call event :fund
    else
      # whatever you want
    end
  end
end
于 2013-07-08T18:12:31.880 に答える