使用state_machine gem,有没有办法使事件私有/受保护?

baa*_*h05 5 ruby ruby-on-rails state-machine

我想知道在使用state_machine gem时是否有办法使状态事件变为私有?

我有三个州

未付,待定,已付款.

如果收据未付,则可以触发事件以向用户收费.这会将收据切换为待处理(当​​它与商家服务对话时)然后一旦完成,它将调用付费事件,从而将状态设置为付款.

收据类的用户可以在技术上调用付费事件,即使它没有通过商家运行,也会将收据切换为付款.

注意:这是一个反对的例子......

我非常相信私有和受保护的方法,我想知道如何在state_machine实现的上下文中使用它们.

wic*_*icz 7

我假设你在谈论这个state_machine.

您可以通过在定义之后将它们标记为私有来轻松地将事件转换方法设为私有,例如

class Payment
  attr_reader :state

  state_machine :state, :initial => :pending do
    event :pay do
      transition [:pending] => :paid
    end
  end

  private :pay # that should do!
end
Run Code Online (Sandbox Code Playgroud)

即使它回答了你的问题,我也非常反对.将方法设为私有或受保护,仅关注方法可见性,即您希望在API中公开的内容.在您的情况下,您真正​​应该寻找的是一种在某个时刻控制对某个功能的访问的方法.此要求与您的域逻辑高度耦合,而不是API.

此外,即使您将方法标记为私有,也不能保证任何安全性,因为可以轻松绕过此限制,通过send调用方法,例如payment.send(:pay).

我认为更好的解决方案是在您的交易之前创建某种策略检查或过滤,以确保它们可以被处理,例如

before_transition :pending => :paid, :do => :check_merchant

def check_merchant
  really_paid = ... # logic to check with the merchant
    or raise "Payment haven't been processed yet. Hang on a sec"
end
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!