2016-04-07 13 views
1

我用在我的模型定义为这样一个枚举下一个枚举:Ruby on Rails的摆脱目前的模式的枚举值

enum role: [:member, :content_creator, :moderator, :admin] 

我想要一个简单的方法来从用户的当前角色的下一个角色,所以我想出了这个:

def self.next_role(user) 
    begin 
    User.roles.drop(User.roles[user.role] + 1).to_enum.next 
    rescue StopIteration 
    nil 
    end 
end 

在视图中,我想可能向产品中添加下列方法链:[...].first.humanize.titleize

我只是有点担心我的解决方案在这里,但主要想知道是否有更好的(阅读:更多内置)的方式来得到我后?我知道那里只有四个枚举,我承认我开始使用if ... elsif ... etc.执行。换句话说,我发现自己比Ruby本身更擅长Rails。有人可以详细说明一个“应该”如何做到这一点?

+0

这是否处理包装? ':admin'的“下一个”是什么? – tadman

+0

拍摄。很好的问题。你认为'无'作为候选人?我希望该方法表示':admin'后面没有任何内容。 –

+0

您正在定义非标准行为,因此您需要制定规则。我只是说你需要考虑这样的情况,以确保它始终如一地以有意义的方式工作。 – tadman

回答

2

User.roles只是一个ActiveSupport::HashWithIndifferentAccess,看起来像:

{ 'member' => 0, 
    'content_creator' => 1, 
    'moderator' => 2, 
    'admin' => 3 } 

使用,这种解决方案是非常接近你的,但没有异常处理。我也将这样做作为用户的实例方法,而不是类方法。

以字符串形式返回后续作用,零如果当前的角色为:admin

def next_role 
    User.roles.key(User.roles[role] + 1) 
end 

然后,您可以拨打电话(红宝石为&.安全导航操作需要2.3)

user.next_role&.humanize 
+0

o_0(我喜欢它)。我真的很喜欢你的解决方案。 –

+0

是不是很担心引用g'User.roles'两次?我同意你的看法,这应该是一个实例方法,因为我总是要求下一个枚举参考当前用户。但我认为它应该是一种类方法,因为整个角色集合并不真正是特定用户的关注点,而是一般用户的概念。你不同意吗? –

+1

根据我的经验,访问枚举哈希不是一个性能问题,当然不支持生成视图。我认为关于“总是询问......参考...用户”这一点是我跳出来说的:这应该是一种实例方法,显然它可以以任何方式工作。实际上,实例方法导致键入的字符更少来电:) –

0

这是如何抓住你?好,所以它不是真的更“内置”。但是我认为它与你的解决方案(这非常聪明的iMo)有所不同,至少可以提供一些不同的元素来加入。

def self.next_role(user) 
    next_role = user.role.to_i + 1 
    next_role == self.roles.length ? nil : self.roles.invert[next_role] 
    end 
+0

我也喜欢你的解决方案!它绝对不会再提到'User.roles',这真的是我最大的抱怨,我会继续研究它... –

+0

你也在你的视图中链的起始位置不需要。 – matt721

+0

我认为'user.role'将返回一个字符串,这个枚举的名字,然后'.to_i'然后将它变成'0'。 –