Ruby on Rails从当前模型的枚举值获得下一个枚举

时间:2016-04-07 02:29:12

标签: ruby-on-rails ruby ruby-on-rails-4 enumeration enumerable

我在我的模型中使用枚举这样定义:

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.开始了我的实现。换句话说,我发现自己对Rails的熟练程度要高于Ruby本身。有人可以详细说明一个人应该如何"这样做?

2 个答案:

答案 0 :(得分:2)

User.roles只是一个ActiveSupport::HashWithIndifferentAccess,如下所示:

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

使用它,这个解决方案非常接近你的,但没有异常处理。我也会将此作为User上的实例方法,而不是类方法。

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

,则返回nil
def next_role
  User.roles.key(User.roles[role] + 1)
end

然后您可以调用(&.安全导航操作符所需的ruby 2.3)

user.next_role&.humanize

答案 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