Module: Ruact::ValidationErrorsCollector
- Extended by:
- ActiveSupport::Concern
- Included in:
- Controller, Server
- Defined in:
- lib/ruact/validation_errors_collector.rb
Overview
Story 13.3 (FR98) — the per-request validation-error collector, shared by
Server (Bucket-2 JSON-body injection + redirect flash stash) and
Controller (page-render errors prop + redirect-back flash read).
This is the opt-in half of the Inertia-style errors round-trip
(design (B), the explicit-allowlist grain that 13.1/13.2 reinforced — NO
auto-injection, NO globally reserved prop on every response). A host action
opts in with a single call after its save attempt:
def create
@post = Post.new(post_params)
if @post.save
redirect_to @post
else
ruact_errors(@post) # registers {attr => [full messages]}
render :new # (Bucket 1) or fall through (Bucket 2)
end
end
Because the canonical shape derives from record.errors (empty on a valid
record), the SAME ruact_errors(@post) call yields {} on success and the
populated map on failure — the "always present, same code path" invariant of
AC1, delivered per-action without reserving a global prop name or disturbing
the Story 9.2 Bucket-2 204 No Content contract for an untouched collector.
The reader form (no argument) returns the always-present hash for binding to a form component on the page render:
Constant Summary collapse
- RUACT_ERRORS_FLASH_KEY =
Flash key the Bucket-1 redirect-back round-trip stashes the canonical errors under (single-use, session-backed — the exact Inertia semantics).
:ruact_errors- RESERVED_ASSIGN_KEYS =
view_assignskeys (ivar names without the leading@) that must NEVER serialize into a Bucket-2 body: the two collector internals (Rails only filters a fixed set of@_-named ivars, not every@__-prefixed one), and the reservederrorsoutput key itself (a stray dev ivar literally named@errorsis dropped so it can neither clobber the round-trip key nor trip strict serialization — the collector is the source of truth). %w[__ruact_errors __ruact_errors_touched errors].freeze
Instance Method Summary collapse
-
#ruact_errors(record = NOT_GIVEN) ⇒ Object
Dual-purpose helper.
Instance Method Details
#ruact_errors(record) ⇒ Hash{String=>Array<String>} #ruact_errors ⇒ Hash{String=>Array<String>}
Dual-purpose helper.
ruact_errors(@post) → COLLECT: normalize the record's errors into the
canonical `{attr => [full messages]}` shape, merge it into the
per-request collector, mark the collector touched, and return the
normalized hash (so it can also be used inline).
ruact_errors → READ: return the always-present collector (`{}` by
default), for binding to a form component on the page render.
Merging across multiple records is additive per attribute (later calls
union their messages onto earlier ones), so an action validating several
records surfaces them under one errors object.
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/ruact/validation_errors_collector.rb', line 82 def ruact_errors(record = NOT_GIVEN) return __ruact_errors if record.equal?(NOT_GIVEN) normalized = ServerFunctions::ValidationErrors.normalize(record) @__ruact_errors_touched = true __ruact_errors.merge!(normalized) do |_attribute, existing, incoming| existing | incoming end normalized end |