使用具有大量事务条件的状态机

had*_*ees 1 ruby-on-rails state-machine e-commerce ruby-on-rails-4

我正在rails 4上写一个类似于kickstarterindiegogo的电子商务平台.产品的状态在很大程度上取决于各种条件,例如订单是否足够.因此,例如,如果我使用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
Run Code Online (Sandbox Code Playgroud)

然后我可能会创建一个模型观察者,以便每次下订单时我都会检查product.has_enough_orders?,如果返回,true我会调用product.fund!.因此has_enough_orders?被多次检查.这似乎不是很有效.

另外product.launch!还有类似的问题.我能想到实现它的最好方法是使用类似的工具sidekiq来检查是否有任何预先推出的产品通过他们的launch_at时间.然而,这看起来同样很脏.

我只是在想它,或者你通常会如何使用状态机?

Tal*_*kov 5

我只是修改了你的状态机以更好地处理条件.

你可以使用after_transitionbefore_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
Run Code Online (Sandbox Code Playgroud)