Lesson 5 — BoardForm and self-permitting forms
BoardForm
In standard Rails, scaffolding generates a _form partial shared between new and edit views. The partial handles both creating and updating a record — form_with infers the correct action and HTTP method from whether the model is persisted.
We follow the same pattern in Phlex. The minimal Views::Boards::New we built in Lesson 1 used inline builder methods directly. We now replace it with a dedicated BoardForm view fragment — the Phlex equivalent of the Rails _form partial — shared between a proper New view and a new Edit view.
The result is the same structure Rails developers already know:
- _form partial → Views::Boards::BoardForm
- new.html.erb → Views::Boards::New
- edit.html.erb → Views::Boards::Edit
With one meaningful improvement: BoardForm declares its own permitted parameters via the PERMITTED constant, so the controller never needs to maintain a separate list.
BoardForm is an app-specific view fragment — not a generic form
abstraction. It knows about Board, uses our primitives, and handles
its own error display. It lives under Views:: rather than
Components:: because it is app-specific and not a portable library
component.
|
|
Self-permitting forms
BoardForm knows which fields it renders. The PERMITTED constant
pattern means the controller never needs to maintain a separate list:
|
|
params.expectvsparams.require— Rails 8 introducesparams.expectas the preferred way to handle strong parameters. It’s safer than the.require.permitchain because it handles malformed params gracefully with a 400 response rather than a 500 error. See the Rails docs for the full details.
Add a field to BoardForm and it is automatically permitted. Remove a
field and it is automatically removed. The controller never changes.
PERMITTED is a frozen array for three reasons:
- Load time — evaluated once, not on every request
- Testable —
assert_includes Views::Boards::BoardForm.permitted, :name - Composable —
SubForm.permitted = ParentForm.permitted + [:extra]
For nested attributes the pattern extends naturally:
|
|
Views::Boards::New
|
|
Views::Boards::Edit
|
|
BoardForm works identically for new and edit — form_with detects
model.persisted? and sets the correct method and URL. The submit
button label changes via @board.persisted?.