adzap/active_enum

Add functionality to get id and name of enum by a method

ka8725 opened this issue · 0 comments

It would be great to have ability to get id of enum or name by method. For example, say we have this enum:

class UserRole < ActiveEnum::Base
  value name: :user
  value name: :admin
  value name: :super_admin
end

I want to get user role with such code: UserRole.user # => "User" where "User" here is a translation. And its id: UserRole.user_id # => 1. When I fetch the stuff with method te code is more reliable - it's like having constants for each enum, that's why we want to have this functionality in the gem.

In our project we have implemented this with the following module:

module BaseActiveEnum
  extend ActiveSupport::Concern

  included do
    class << self
      alias_method :names, :to_select
    end

    private

    def self.origin_names_with_ids
      @origin_names_with_ids ||= has_translation? ? translation.keys.zip(1..names.size) : names
    end

    def self.i18n_key
      @i18n_key ||= self.name.underscore
    end

    def self.has_translation?
      translation.is_a?(Hash)
    end

    def self.translation
      @translation ||= I18n.t(i18n_key, scope: :active_enum)
    end

    public

    origin_names_with_ids.each do |pair|
      name, id = pair
      name = name.to_s.gsub(/\s+/, '').underscore
      define_singleton_method(name) { self[id] }
      define_singleton_method("#{name}_id") { self[name] }
    end

  end
end

Then including it to the enum: UserRole.include(BaseActiveEnum) gives us the requested functionality. I want to share this with you and ask is it reasonable to push this to the gem or not. What do you think? If you reject my proposal anyway the solution may be useful for somebody. But this gem is the most reliable and simplest which I've used as enum, and I believe that this functionality will make it much better.