aasm ruby​​ gem:超级用户没有限制

时间:2016-04-07 21:54:32

标签: ruby-on-rails ruby state-machine aasm

鉴于下一个模型使用 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一样。

所以,据我所知,我需要的是在运行时解决转换的 。如果用户是超级用户,来自将是所有状态,但如果用户不是超级用户,则每个用户将具有不同的状态。

有没有干净的方法呢?你有什么想法吗?

1 个答案:

答案 0 :(得分: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      
    

    然后,您应该根据用户的角色获得CommonUserJobAdminJob实例并调用状态更改。

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

  3. 请注意,这两项建议都会使您的基础Job课程完全没有aasm验证。这似乎与常见的Rails方式相矛盾,但遵循DCI paradigm,它指出我们应该将系统(域模型)与系统(功能)的内容分离。基类实例应该仍然能够获得其当前状态。