鉴于下一个模型使用 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一样。
所以,据我所知,我需要的是在运行时解决转换的 。如果用户是超级用户,来自将是所有状态,但如果用户不是超级用户,则每个用户将具有不同的状态。
有没有干净的方法呢?你有什么想法吗?
答案 0 :(得分:0)
基于current_user
在模型层中做出决策一直被认为是代码气味,因此实现目标的几种简洁方法可能是:
实现一些继承,例如:
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
实例并调用状态更改。
要实现一些组合(请参阅composition over inheritance),这意味着您将特定于角色的aasm
代码移动到模块并使用特定的一个扩展job
对象运行时。
请注意,这两项建议都会使您的基础Job
课程完全没有aasm
验证。这似乎与常见的Rails方式相矛盾,但遵循DCI paradigm,它指出我们应该将系统(域模型)与系统(功能)的内容分离。基类实例应该仍然能够获得其当前状态。