I'm using an enum in my model defined as such:
enum role: [:member, :content_creator, :moderator, :admin]
I wanted an easy way to get the next role from a user's current role, so I came up with this:
def self.next_role(user)
begin
User.roles.drop(User.roles[user.role] + 1).to_enum.next
rescue StopIteration
nil
end
end
In the view, I'd likely add onto this the following method chain: [...].first.humanize.titleize
.
I'm only somewhat concerned about my solution here, but mainly wanted to know if there was a better (read: more built-in) way to get what I'm after? I know there are only four enums there and I admit I started my implementation with if ... elsif ... etc.
. In other words, I find myself more proficient in Rails than I do with Ruby itself. Can someone elaborate how one "should" do this?
User.roles
is just an ActiveSupport::HashWithIndifferentAccess
that looks like:
{ 'member' => 0,
'content_creator' => 1,
'moderator' => 2,
'admin' => 3 }
Using that, this solution is pretty close to yours but without the exception handling. I would also be doing this as an instance method on User, not a class method.
Returns the subsequent role as a String, nil if the current role is :admin
def next_role
User.roles.key(User.roles[role] + 1)
end
You can then call (ruby 2.3 required for the &.
safe navigation operator)
user.next_role&.humanize