Module: PersistentEnum::ClassMethods

Defined in:
lib/persistent_enum.rb

Instance Method Summary collapse

Instance Method Details

#acts_as_enum(required_constants, name_attr: :name, sql_enum_type: nil, &constant_init_block) ⇒ Object



20
21
22
23
24
# 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: "#{enum_name}_id") ⇒ Object

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.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 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