module PersistentEnum::ClassMethods

Public Instance Methods

acts_as_enum(required_constants, name_attr: :name, sql_enum_type: nil, &constant_init_block) click to toggle source
# File lib/persistent_enum.rb, line 20
def acts_as_enum(required_constants, name_attr: :name, sql_enum_type: nil, &constant_init_block)
  include ActsAsEnum
  enum_spec = EnumSpec.new(constant_init_block, required_constants, name_attr, sql_enum_type)
  initialize_acts_as_enum(enum_spec)
end
belongs_to_enum(enum_name, class_name: enum_name.to_s.camelize, foreign_key: " click to toggle source

Sets up a association with an enumeration record type. Key resolution is done via the enumeration type's cache rather than ActiveRecord. The setter accepts either a model type or the enum constant name as a symbol or string.

# File lib/persistent_enum.rb, line 30
def belongs_to_enum(enum_name, class_name: enum_name.to_s.camelize, foreign_key: "#{enum_name}_id")
  target_class = class_name.constantize

  define_method(enum_name) do
    target_id = read_attribute(foreign_key)
    target_class[target_id]
  end

  define_method("#{enum_name}=") do |enum_member|
    id = case enum_member
         when nil
           nil
         when target_class
           enum_member.ordinal
         else
           m = target_class.value_of(enum_member)
           raise NameError.new("#{target_class}: Invalid enum constant '#{enum_member}'") if m.nil?

           m.ordinal
         end
    write_attribute(foreign_key, id)
  end

  # All enum members must be valid
  validates foreign_key, inclusion: { in: ->(_r) { target_class.all_ordinals } }, allow_nil: true

  # New enum members must be currently active
  validates foreign_key, inclusion: { in: ->(_r) { target_class.ordinals } }, allow_nil: true, on: :create
end