Class: LcpRuby::VirtualFields::VirtualField

Inherits:
Object
  • Object
show all
Defined in:
lib/lcp_ruby/virtual_fields/virtual_field.rb

Overview

Field-shaped object backing a VirtualForm input. Implements the duck-typed contract that ‘form_helper.rb` `render_form_input` (and its sub-renderers) read from `field_def`:

* #type                          — used for the json text-branch and array?/attachment? predicates
* #enum?                         — used by render_select_input / render_radio_input / render_json_field_input
* #enum_value_names              — same
* #enum_label_for(v, model_name:) — same
* #attachment_options            — used by render_file_upload_input (boot-rejected for filter forms in v1)

Anything else (column_for_attribute, type_definition, attachment?, computed?, …) is NOT read by render_form_input — confirmed by exhaustive callsite audit at spec § 5 step 8.

‘am_type` is consumed by `VirtualForm` when it declares the synthetic AM::Model class’s ‘attribute(name, type)`. Defaults to `:string`; consumers pass `LcpRuby::VirtualFields::Types::ArrayOf` for multi: fields.

Spec: docs/design/page_filters_as_virtual_forms.md § 5 step 6.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, input_type:, input_options: {}, default: nil, am_type: :string, label_key: nil, placeholder: nil) ⇒ VirtualField

Returns a new instance of VirtualField.



29
30
31
32
33
34
35
36
37
38
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 29

def initialize(name:, input_type:, input_options: {}, default: nil,
               am_type: :string, label_key: nil, placeholder: nil)
  @name          = name.to_s
  @input_type    = input_type.to_s
  @input_options = input_options || {}
  @default       = default
  @am_type       = am_type
  @label_key     = label_key
  @placeholder   = placeholder
end

Instance Attribute Details

#am_typeObject (readonly)

Returns the value of attribute am_type.



26
27
28
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 26

def am_type
  @am_type
end

#defaultObject (readonly)

Returns the value of attribute default.



26
27
28
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 26

def default
  @default
end

#input_optionsObject (readonly)

Returns the value of attribute input_options.



26
27
28
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 26

def input_options
  @input_options
end

#input_typeObject (readonly)

Returns the value of attribute input_type.



26
27
28
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 26

def input_type
  @input_type
end

#label_keyObject (readonly)

Returns the value of attribute label_key.



26
27
28
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 26

def label_key
  @label_key
end

#nameObject (readonly)

Returns the value of attribute name.



26
27
28
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 26

def name
  @name
end

#placeholderObject (readonly)

Returns the value of attribute placeholder.



26
27
28
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 26

def placeholder
  @placeholder
end

Instance Method Details

#attachment_optionsObject

render_file_upload_input reads this; file_upload is boot-rejected for filter forms (see FilterFormValidator BOOT_REJECT set), so the branch is unreachable in v1. Returning nil keeps the contract honest for future consumers (wizards, virtual show).



75
76
77
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 75

def attachment_options
  nil
end

#attribute_namesObject

Names of the AM::Model attributes that back this field. Most input types map 1:1 to a single attribute (‘[name]`). `date_range` (and any future `<x>_range` sibling) declares a paired set of attributes — see spec § 5 step 5: “the input declares two separate AM attributes (`<field>_from: :date`, `<field>_to: :date`)”.

VirtualForm consumes this both for ‘klass.attribute(…)` declaration and for the strong-params whitelist, so that URL keys like `page_filter` reach `to_model.attributes` without being silently dropped.



89
90
91
92
93
94
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 89

def attribute_names
  case @input_type
  when "date_range" then [ "#{@name}_from", "#{@name}_to" ]
  else                  [ @name ]
  end
end

#attribute_type(_attr_name = nil) ⇒ Object

AM type to apply at each ‘attribute_names` site. Range inputs decompose each paired attribute as a scalar of the inner type (multi: is rejected on range inputs by FilterFormValidator).



99
100
101
102
103
104
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 99

def attribute_type(_attr_name = nil)
  case @input_type
  when "date_range" then ActiveModel::Type.lookup(:date)
  else                  @am_type
  end
end

#enum?Boolean

Filter forms do not declare AR enums; values are passed through ‘input_options.values:` (rendered via field_config — see FilterForm#field_config_for in PR 5). The stub returns falsy so render_select_input takes the explicit_options branch.

Returns:

  • (Boolean)


57
58
59
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 57

def enum?
  false
end

#enum_label_for(value, model_name: nil) ⇒ Object

rubocop:disable Lint/UnusedMethodArgument



66
67
68
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 66

def enum_label_for(value, model_name: nil)
  value.to_s
end

#enum_value_namesObject



61
62
63
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 61

def enum_value_names
  []
end

#typeObject

Returns the underlying field type as a string. VirtualField uses ‘input_type` as the source of truth; `Metadata::FieldDefinition` uses an AR-column type. The two are not always the same, but `render_form_input` only branches on `type == “json”` for the text-area JSON pretty-printing path — filter forms don’t expose ‘json` (it’s not in ALLOWED_FILTER_INPUT_TYPES), so this returns the input_type verbatim.



49
50
51
# File 'lib/lcp_ruby/virtual_fields/virtual_field.rb', line 49

def type
  @input_type
end