简体   繁体   English

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

[英]aasm ruby gem: super user without restrictions

Given the next model using the aasm gem: 鉴于使用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

I have 2 types of users on my web application (regular users, and super users). 我的Web应用程序上有两种类型的用户(普通用户和超级用户)。 I need super users type, beeing able to call the event they want. 我需要超级用户类型,能够调用他们想要的事件。 Like calling #run on a job with state=cleaning. 就像在state = cleaning的工作上调用#run一样。

So, as I understand, what I need is to resolve the transition's from at runtime. 所以,按照我的理解,我需要的是在运行时解决过渡的。 If the user is a superuser, the from would be all the states, but if the user is not a super user, each from would have different states. 如果用户是超级用户,则from将是所有状态,但如果用户不是超级用户,则每个用户将具有不同的状态。

Is there any clean way to do that? 有没有干净的方法呢? Do you have any ideas? 你有什么想法?

Making decisions in a model layer based on current_user has always been considered a code smell, so a couple of clean ways to achieve your goal could be: 在基于current_user的模型层中做出决策一直被认为是代码气味,因此实现目标的几种简洁方法可能是:

  1. To implement some inheritance, like: 要实现一些继承,例如:

     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 

    Then you should get a CommonUserJob or AdminJob instance based on your user's role and call a state change. 然后,你应该得到一个CommonUserJobAdminJob根据用户的角色实例,并调用的状态变化。

  2. To implement some composition (refer to composition over inheritance ), which would mean you move your role-specific aasm code to modules and extend job object with a particular one at a runtime. 实现一些组合(请参阅组合而不是继承 ),这意味着您将特定aasm角色的aasm代码移动到模块并在运行时使用特定的一个扩展job对象。

Note that both of this suggestions leave your base Job class without any aasm validations at all. 请注意,这两个建议都会使您的基本Job类完全没有任何aasm验证。 This seems to contradict a common Rails way, but follows a DCI paradigm , which states that we should decouple what the system is (domain model) from what the system does (functionality). 这似乎与常见的Rails方式相矛盾,但遵循DCI范式 ,该范例指出我们应该将系统(域模型)与系统(功能)的内容分离。 Base class instances should still be able to get its current state though. 基类实例应该仍然能够获得其当前状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM