【问题标题】:Ruby on Rails get next enum from current model's enum valueRuby on Rails 从当前模型的枚举值中获取下一个枚举
【发布时间】:2016-07-27 17:09:00
【问题描述】:

我在我的模型中使用了一个枚举,定义如下:

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 本身更精通。有人能详细说明一个人“应该”如何做到这一点吗?

【问题讨论】:

  • 处理包装吗? :admin 的“下一步”是什么?
  • 射击。好问题。您如何看待nil 作为候选人?我希望该方法能够传达:admin 之后什么都没有。
  • 您在这里定义了非标准行为,因此您需要制定规则。我只是说你需要考虑这样的情况,以确保它始终如一地以有意义的方式发挥作用。
  • 同意。我认为这就是我希望它工作的方式,但我看到在场景中我得到了一个异常而不是 nil :(
  • 我更新了我建议的解决方案,以考虑当前角色为管理员时对下一个角色的看法。感谢您的意见@tadman

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


【解决方案1】:

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

【讨论】:

  • o_0(我喜欢它)。我真的很喜欢你的解决方案。
  • 担心引用User.roles 两次有错吗?我同意你的观点,这应该是一个实例方法,因为我总是要求下一个枚举参考当前用户。但我认为它应该是一个类方法,因为整个角色集合并不是特定用户真正关心的问题,而是一般用户的概念。你不同意吗?
  • 根据我的经验,访问枚举哈希不是性能问题,当然也不支持视图的生成。我认为关于“总是询问……关于……用户”这句话让我跳出来说:这应该是一个实例方法。显然它适用于任何一种方式。务实地,实例方法导致要输入的字符更少来电者:)
【解决方案2】:

这怎么吸引你?好的,所以它并不是真的更“内置”。但我认为它与您的解决方案(这在 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

【讨论】:

  • 我也喜欢你的解决方案!它绝对不会多次提及User.roles,这真的是我最大的抱怨。我会继续考虑...
  • 你也不需要 .first 在你的视图链的开头
  • 我认为user.role 将返回一个字符串,即枚举的名称,然后.to_i 将其转换为0
  • .to_i 会给你与 User.roles[.role] 相同的值,而不是总是 0。
猜你喜欢
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多