module Mongoid::Enum::ClassMethods

Class Methods

class Model

include Mongoid::Enum

enum :status, in: %i( waiting approved dismissed )

Public Instance Methods

enum(field_name, values, options = {}) click to toggle source

Main class method

# File lib/mongoid/enum.rb, line 20
def enum(field_name, values, options = {})
  options = default_options.merge(options)

  set_values_constant field_name, values

  create_field field_name, options, values
  create_i18n_helper model_name, field_name, options
  create_values_helper model_name, field_name, options

  create_validations field_name, values, options
  define_value_scopes_and_accessors field_name, values, options
  if options[:multiple]
    define_array_field_writer field_name
  else
    define_field_writer field_name
  end
end

Private Instance Methods

create_field(field_name, options, values) click to toggle source
# File lib/mongoid/enum.rb, line 53
def create_field(field_name, options, values)
  type = options[:multiple] && Array || Symbol
  default = \
    if options.key?(:default)
      options[:default]
    else
      options[:multiple] ? [] : values.first
    end
  field field_name, type: type, default: default
end
create_i18n_helper(main_model, field_name, options) click to toggle source
# File lib/mongoid/enum.rb, line 91
def create_i18n_helper(main_model, field_name, options)
  return if options[:i18n].is_a?(FalseClass)
  if options[:multiple]
    define_method("#{field_name}_i18n") do
      return if self[field_name].blank?
      self[field_name].map do |k|
        I18n.translate("mongoid.enums.#{main_model.to_s.underscore}."\
                       "#{field_name}.#{k}")
      end
    end
  else
    define_method("#{field_name}_i18n") do
      return if self[field_name].blank?
      I18n.translate("mongoid.enums.#{main_model.to_s.underscore}."\
                   "#{field_name}.#{self[field_name]}")
    end
  end
end
create_validations(field_name, values, options) click to toggle source
# File lib/mongoid/enum.rb, line 77
def create_validations(field_name, values, options)
  return unless options[:validate]
  if options[:multiple]
    validates field_name, :'mongoid/enum/validators/multiple' => {
      in: values.map(&:to_sym),
      allow_blank: !options[:required]
    }
  else
    validates field_name,
              inclusion: { in: values },
              allow_blank: !options[:required]
  end
end
create_values_helper(main_model, field_name, options) click to toggle source
# File lib/mongoid/enum.rb, line 110
def create_values_helper(main_model, field_name, options)
  return if options[:i18n].is_a?(FalseClass)
  define_singleton_method("#{field_name}_values") do
    I18n.translate("mongoid.enums.#{main_model.to_s.underscore}."\
                   "#{field_name}").map { |k, v| [v, k] }
  end
end
default_options() click to toggle source
# File lib/mongoid/enum.rb, line 40
def default_options
  {
    multiple: false,
    required: true,
    validate: true
  }
end
define_array_accessor(field_name, value) click to toggle source
# File lib/mongoid/enum.rb, line 132
def define_array_accessor(field_name, value)
  class_eval "def #{value}?() self.#{field_name}.include?(:#{value}) end"
  class_eval "def #{value}!() update_attributes! :#{field_name} => (self.#{field_name} || []) + [:#{value}] end"
end
define_array_field_writer(field_name) click to toggle source
# File lib/mongoid/enum.rb, line 64
def define_array_field_writer(field_name)
  define_method("#{field_name}=") do |vals|
    write_attribute(field_name, Array(vals).compact.map(&:to_sym))
  end
end
define_field_writer(field_name) click to toggle source
# File lib/mongoid/enum.rb, line 70
def define_field_writer(field_name)
  define_method("#{field_name}=") do |val|
    val = nil if val.respond_to?(:empty?) && val.empty?
    write_attribute(field_name, val)
  end
end
define_string_accessor(field_name, value) click to toggle source
# File lib/mongoid/enum.rb, line 137
def define_string_accessor(field_name, value)
  class_eval "def #{value}?() self.#{field_name} == :#{value} end"
  define_method("#{value}!") do
    update_attributes! :"#{field_name}" => :"#{value}"
  end
end
define_value_scopes_and_accessors(field_name, values, options) click to toggle source
# File lib/mongoid/enum.rb, line 118
def define_value_scopes_and_accessors(field_name, values, options)
  values.each do |value|
    unless options[:scope].is_a?(FalseClass)
      scope value, -> { where(field_name => value) }
    end
    next if options[:accessor].is_a?(FalseClass)
    if options[:multiple]
      define_array_accessor(field_name, value)
    else
      define_string_accessor(field_name, value)
    end
  end
end
set_values_constant(name, values) click to toggle source
# File lib/mongoid/enum.rb, line 48
def set_values_constant(name, values)
  const_name = name.to_s.upcase
  const_set const_name, values
end