1

给定使用aasm gem的下一个模型:

class Job
  include AASM

  aasm do
    state :sleeping, :initial => true
    state :running, :cleaning

    event :run do
      transitions :from => :sleeping, :to => :running
    end

    event :clean do
      transitions :from => :running, :to => :cleaning
    end

    event :sleep do
      transitions :from => [:running, :cleaning], :to => :sleeping
    end
  end
end

我的网络应用程序上有两种类型的用户(普通用户和超级用户)。我需要超级用户类型,能够调用他们想要的事件。就像在 state=cleaning 的作业上调用 #run。

因此,据我了解,我需要的是在运行时解决转换的问题。如果用户是超级用户,则from将是所有状态,但如果用户不是超级用户,则每个 from 将具有不同的状态。

有什么干净的方法可以做到这一点吗?你有什么想法?

4

1 回答 1

0

在基于模型层的决策current_user一直被认为是代码异味,因此实现目标的几种干净方法可能是:

  1. 要实现一些继承,例如:

    CommonUserJob < Job
      # move your current AASM validations here
    end
    
    AdminJob < Job
      aasm do
        event :run do
          all_states = Job.aasm.states.map{|i| i.name}
          transitions :from => all_states, :to => :running
        end
        # other events here in same manner
      end
    end      
    

    然后您应该根据您的用户角色获取一个CommonUserJob或实例并调用状态更改。AdminJob

  2. 要实现某些组合(请参阅基于继承的组合),这意味着您将特定于角色的代码移动到模块并在运行时使用特定的对象aasm扩展对象。job

请注意,这两个建议都使您的基Job类根本没有任何aasm验证。这似乎与常见的 Rails 方式相矛盾,但遵循DCI 范式,该范式指出我们应该将系统是什么(域模型)与系统所做的(功能)分离。不过,基类实例应该仍然能够获得其当前状态。

于 2016-04-08T06:48:54.413 回答