2016-04-07 56 views
1

超级用户:AASM红宝石宝石:不使用<strong>AASM</strong>宝石鉴于今后的机型限制

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 

我有2种在我的Web应用用户(普通用户和超级用户)。我需要超级用户类型,可以打电话给他们想要的事件。就像在state = cleaning的工作上调用#run一样。

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

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

回答

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对象。

注意两者的这个建议,在所有离开你的基地Job类没有任何aasm验证。这似乎与通用的Rails方式相矛盾,但遵循DCI paradigm,该规定声明我们应该将系统(域模型)与系统所做的功能(功能)分开。尽管基类实例仍然能够获得其当前状态。