Module: Glib::EnumSymbolization

Extended by:
ActiveSupport::Concern
Included in:
ApplicationRecord
Defined in:
app/models/concerns/glib/enum_symbolization.rb

Overview

Class-level helper for declaring enums that read back as symbols, can never be persisted nil, and — crucially — know their attribute type even before the backing column exists.

Preferred form (declares everything in one call; use INSTEAD of a bare enum). Because it calls attribute before enum, the enum's type comes from the declared values rather than from column introspection, so a model loaded against a not-yet-migrated column (fresh deploy, eager-loaded CI, an un-migrated local DB) no longer raises "Undeclared attribute type for enum":

class Order < ApplicationRecord
include Glib::EnumSymbolization

enum_symbolize :payment_status, { draft: 0, pending: 1, finalized: 2 }
enum_symbolize :finalize_intent, { unknown: 0, charge: 1 }, prefix: true
end

The attribute type is inferred from the values: string values back a :string column, everything else (integer-keyed hashes, positional arrays) backs an :integer column. Pass the values as a braced hash — a bare key: 0 list is parsed as keyword options, not values.

Legacy form (attach presence + symbolized reader to enum(s) already declared above). Prefer the form above for new code:

enum :status, { draft: 0, published: 1 }
enum_symbolize :status

Both forms add validates :attr, presence: true (a nil enum has no symbolic key and is almost always a bug) and override the reader to return a symbol, so callers can compare with record.status == :active without tracking which form they're holding (see backend/01a_defensive_programming.md item 7).

Class Method Summary collapse

Class Method Details

.backing_type(values) ⇒ Object

Infer the attribute type backing an enum from its declared values, so the type never depends on the (possibly not-yet-migrated) DB column. A hash whose values are strings backs a :string column; integer-keyed hashes and positional arrays back an :integer column.



75
76
77
78
# File 'app/models/concerns/glib/enum_symbolization.rb', line 75

def self.backing_type(values)
  first = values.is_a?(Hash) ? values.values.first : nil
  first.is_a?(String) ? :string : :integer
end