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



28
29
30
31
32
# File 'lib/persistent_enum.rb', line 28

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.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/persistent_enum.rb', line 38

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