Class: LcpRuby::Types::BuiltInTypes
- Inherits:
-
Object
- Object
- LcpRuby::Types::BuiltInTypes
- Defined in:
- lib/lcp_ruby/types/built_in_types.rb
Constant Summary collapse
- RESERVED_ENUM_NAMES =
Field names that cause AR’s ‘enum` macro to raise `ArgumentError` at boot. AR’s ‘enum :name, […]` generates a class method named after the pluralized field and rejects when that pluralized form is already a class method on the AR class.
Empirically (Rails 8.x), only ‘value` triggers this — AR defines `Klass.values` via the attributes/Relation surface, so `enum :value, […]` would generate a clashing `Klass.values`. Other plausible-sounding names (where, find, count, etc.) DO NOT clash: their pluralized forms (`wheres`, `finds`, `counts`) aren’t AR class methods, so AR’s enum macro accepts them. The single known clash is listed here as a tested baseline.
Correctness is enforced by ‘built_in_types_spec.rb` “RESERVED_ENUM_NAMES correctness” — a runtime test that exercises AR’s actual ‘enum` macro for each entry, asserting an ArgumentError. If a future Rails version adds new clashes, the test catches them and this list is extended.
%w[value].freeze
- DEFINITIONS =
Phase 1 invariant: NO ‘validations:` key on any BASE_TYPES backfill entry. `apply_type_default_validations` (validation_applicator.rb:22) gates only on `if field.type_definition`; once a string field has any type_definition, that path runs. A `validations:` array on a backfilled base type would silently apply those validators to every typed field at runtime — breaking the “Phase 1 is behavior-neutral” claim.
{ # ----- BASE_TYPES backfill (registry-shaping, behavior-neutral) ----- "string" => { name: "string", base_type: "string" }, "text" => { name: "text", base_type: "text", renderer: "truncate", default_index_visible: false }, "integer" => { name: "integer", base_type: "integer" }, "float" => { name: "float", base_type: "float" }, "decimal" => { name: "decimal", base_type: "decimal" }, "boolean" => { name: "boolean", base_type: "boolean", renderer: "boolean_icon", null_false_validation: [ { "type" => "inclusion", "options" => { "in" => [ true, false ] } } ] }, "date" => { name: "date", base_type: "date" }, "datetime" => { name: "datetime", base_type: "datetime" }, "enum" => { name: "enum", base_type: "enum", renderer: "badge", reserved_clashes: RESERVED_ENUM_NAMES }, "file" => { name: "file", base_type: "file", default_index_visible: false }, "rich_text" => { name: "rich_text", base_type: "rich_text", renderer: "rich_text", default_index_visible: false }, "json" => { name: "json", base_type: "json", renderer: "code", default_index_visible: false }, "uuid" => { name: "uuid", base_type: "uuid" }, "attachment" => { name: "attachment", base_type: "attachment", renderer: "attachment_preview", default_index_visible: false }, "array" => { name: "array", base_type: "array", default_index_visible: false }, # ----- Business types (existing) ----- "email" => { name: "email", base_type: "string", transforms: %w[strip downcase], validations: [ { "type" => "format", "options" => { "with" => '\A[^@\s]+@[^@\s]+\z', "allow_blank" => true } } ], input_type: "email", renderer: "email_link", column_options: { limit: 255 } }, "phone" => { name: "phone", base_type: "string", transforms: %w[strip normalize_phone], validations: [ { "type" => "format", "options" => { "with" => '\A\+?\d{7,15}\z', "allow_blank" => true } } ], input_type: "tel", renderer: "phone_link", column_options: { limit: 50 } }, "url" => { name: "url", base_type: "string", transforms: %w[strip normalize_url], validations: [ { "type" => "format", "options" => { "with" => '\A(https?|ftp)://[^\s/$.?#].[^\s]*\z', "allow_blank" => true } } ], input_type: "url", renderer: "url_link", column_options: { limit: 2048 } }, "color" => { name: "color", base_type: "string", transforms: %w[strip downcase], validations: [ { "type" => "format", "options" => { "with" => '\A#[0-9a-f]{6}\z', "allow_blank" => true } } ], input_type: "color", renderer: "color_swatch", column_options: { limit: 7 } }, # Use for FK columns that reference Rails' default bigint primary # key — `:integer` would silently create a 4-byte INT column that # mismatches the 8-byte BIGINT on JOINs. "bigint" => { name: "bigint", base_type: "integer", column_type: :bigint } }.freeze
Class Method Summary collapse
-
.register_all! ⇒ Object
Idempotent: safe to call multiple times.
Class Method Details
.register_all! ⇒ Object
Idempotent: safe to call multiple times. Each entry is re-built and ‘TypeRegistry.register` overwrites by name. Called by the engine at boot (`engine.rb:246`) and lazily from the entity generator (`entity_generator.rb#parse_fields`) for the standalone `rails generate` path where the engine doesn’t fully boot.
148 149 150 151 152 153 |
# File 'lib/lcp_ruby/types/built_in_types.rb', line 148 def register_all! DEFINITIONS.each do |name, attrs| type_def = TypeDefinition.new(**attrs) TypeRegistry.register(name, type_def) end end |