Skip to content

Instantly share code, notes, and snippets.

@mmalek-sa
Created August 16, 2018 20:45
Show Gist options
  • Save mmalek-sa/86096220ccd06fe46f0c09306e9d382d to your computer and use it in GitHub Desktop.
Save mmalek-sa/86096220ccd06fe46f0c09306e9d382d to your computer and use it in GitHub Desktop.
String enums are useful when you want to keep the actual string instead of integer in database, This gist add the validation to make sure users are passing correct values to model.
require 'active_support/concern'
module StringEnums
extend ActiveSupport::Concern
class_methods do
def string_enum(enums_hash)
enum_name = enums_hash.keys.first.to_s
define_singleton_method(enum_name.pluralize) do
result = {}
enums_hash[enum_name.to_sym].each { |enum_key| result[enum_key] = I18n.t("enums.#{enum_name}.enum_key", :default => enum_key.to_s) }
result
end
validation_method = "validate_#{enum_name}_values"
validate validation_method.to_sym
define_method(validation_method) do
value = send(enum_name)
errors.add(enum_name, I18n.t("validations.invalid_#{enum_name}", default: "Invalid value for #{enum_name}, possible values are: #{self.class.send(enum_name.pluralize).values}")) unless value.blank? or self.class.send(enum_name.pluralize).keys.include?(value.to_sym)
end
end
end
end
# Sample usage of above concern
class User < ActiveRecord::Base
include StringEnums
string_enum user_group: %i[admin manager developer reporter]
end
@mmalek-sa
Copy link
Author

Of course in above sample you need to create the user_group column in database as a string with this migration:

class AddUserGroupToUsers < ActiveRecord::Migration
  def change
    add_column :users, :user_group, :string
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment