Class: CrudComponents::Fields::DynamicField

Inherits:
ComputedField show all
Defined in:
lib/crud_components/fields/dynamic_field.rb

Overview

The field flavor behind a DynamicColumn: a column with no row in the model’s table. It renders like a ComputedField (value typed, or ‘as:`), but the value comes from the column’s resolver block rather than a method on the record, and a ‘preload:` lambda primes a per-page cache so a whole table costs one fetch, not one per row.

Unlike the built-in fields — memoized on the immutable Structure and shared across every request — a DynamicField is built fresh per ‘crud_collection` call, so it may safely hold request state (the loaded cache). Filtering and sorting work only through the column’s ‘filter:`/`sort:` facets; without them the column never reaches SQL, which keeps the query whitelist intact.

Constant Summary

Constants inherited from Base

Base::NON_EDITABLE_COLUMNS

Instance Attribute Summary

Attributes inherited from Base

#facets, #model, #name, #options

Instance Method Summary collapse

Methods inherited from ComputedField

#default_renderer, #renderer

Methods inherited from Base

#apply_derived_filter, #apply_filter, #apply_filter_facet, #apply_sort, #custom_header?, #declared_preloads, #default_editable?, #default_renderer, #derived_filter_control, #derived_filterable?, #derived_sortable?, #eager_load, #editable?, #editable_permitted?, #filter_choices, #filter_control, #filter_facet, #filter_includes_null?, #filterable?, #form_control, #form_partial, #group_label, #group_model, #header, #header_actions, #human_name, #nullable?, #permit_param, #permitted?, #picker_label, #range_filter?, #render_block, #renderer, #renderer_options, #sort_facet, #sortable?

Constructor Details

#initialize(column, model) ⇒ DynamicField

header:/header_actions: arrive via the column’s options and are read by Fields::Base#header / #header_actions / #custom_header? — the layout picks them up through the Collection presenter, same as a declared attribute’s.



18
19
20
21
22
23
# File 'lib/crud_components/fields/dynamic_field.rb', line 18

def initialize(column, model)
  super(column.name, model, column.options, column.facets)
  @value_block = column.value_block
  @preload_block = column.preload_block
  @loaded = nil
end

Instance Method Details

#columnObject

Never backed by a real DB column — keep column/nullable introspection nil so nothing tries to read model.columns_hash.



41
# File 'lib/crud_components/fields/dynamic_field.rb', line 41

def column = nil

#preload!(records) ⇒ Object

Run the batch loader once over the page’s records; the resolver then reads per-record from whatever it returned. Called by the presenter just before rendering, only for the columns that end up visible.



28
29
30
31
# File 'lib/crud_components/fields/dynamic_field.rb', line 28

def preload!(records)
  @loaded = @preload_block&.call(records)
  self
end

#value(record) ⇒ Object



33
34
35
36
37
# File 'lib/crud_components/fields/dynamic_field.rb', line 33

def value(record)
  return super unless @value_block

  @value_block.arity == 1 ? @value_block.call(record) : @value_block.call(record, @loaded)
end