Class: LcpRuby::Export::ValueFormatter
- Inherits:
-
Object
- Object
- LcpRuby::Export::ValueFormatter
- Defined in:
- lib/lcp_ruby/export/value_formatter.rb
Overview
Formats field values for export output based on field type and user-selected options.
Constant Summary collapse
- ENUM_MODES =
%w[label key both].freeze
- BOOLEAN_MODES =
%w[true_false yes_no one_zero].freeze
- DATE_MODES =
%w[iso locale custom].freeze
Instance Method Summary collapse
-
#format(value, field_definition: nil, model_name: nil, raw: false, output: :json) ⇒ Object?
Formatted value (String in label mode, native type in raw mode).
-
#initialize(options = {}) ⇒ ValueFormatter
constructor
A new instance of ValueFormatter.
Constructor Details
#initialize(options = {}) ⇒ ValueFormatter
Returns a new instance of ValueFormatter.
15 16 17 |
# File 'lib/lcp_ruby/export/value_formatter.rb', line 15 def initialize( = {}) @options = ( || {}).transform_keys(&:to_s) end |
Instance Method Details
#format(value, field_definition: nil, model_name: nil, raw: false, output: :json) ⇒ Object?
Returns formatted value (String in label mode, native type in raw mode).
28 29 30 31 32 33 34 35 36 37 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 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/lcp_ruby/export/value_formatter.rb', line 28 def format(value, field_definition: nil, model_name: nil, raw: false, output: :json) return nil if value.nil? type = field_definition&.type || infer_type(value) # has_many → terminal dot-paths (e.g. `tasks.status`, `tasks.due_date`, # `tasks.title`) deliver an Array of terminal values. Format each element # through the SAME type logic and recombine — a single chokepoint so # every type is handled, not just enum. Without it, non-enum Arrays fell # through to scalar parsers: `format_date([d1, d2])` parsed only the # first date (silent data loss) and string terminals emitted the Ruby # array literal `["a", "b"]`. # # Gate on the EXPLICIT field type, not `type`: only a declared `json` # field holds an Array that must serialize as JSON. When the field def # can't be resolved (field_definition nil), `type` would be # `infer_type(Array) == "json"` and wrongly skip the join — so a # has_many dot-path with no resolvable terminal would still emit the # Ruby array literal. Checking field_definition&.type keeps that case # joined. if value.is_a?(Array) && field_definition&.type != "json" formatted = value.map do |v| format(v, field_definition: field_definition, model_name: model_name, raw: raw, output: output) end # Raw JSON wants a native array of typed values; CSV and the # locale-formatted label modes want a single joined cell. return formatted if raw && output != :csv return formatted.compact.join(array_separator) end return format_raw(value, type, output) if raw case type when "enum" format_enum(value, field_definition, model_name) when "date" format_date(value) when "datetime" format_datetime(value) when "boolean" format_boolean(value) when "decimal", "float" format_decimal(value) when "json" value.is_a?(String) ? value : value.to_json else value.to_s end end |