Lesson 1 — form_with in Phlex
The adapter
form_with is a Rails helper that generates a form tag and yields a
form builder. To use it in Phlex, include the adapter in Components::Base:
|
|
With the adapter included, form_with is available in every component
and view without any further setup.
How form_with works in Phlex
form_with yields a form builder object — exactly as in ERB, but the
builder’s output methods push HTML directly to the Phlex buffer:
|
|
CSRF protection is automatic — form_with injects the authenticity
token as a hidden field. You never need to handle it manually.
form_with also detects whether the model is persisted:
- New record →
action="/boards",method="post" - Persisted record →
action="/boards/1",method="post"with a hidden_method=patchfield
One form, two behaviours. No conditional logic needed.
Using form_with builder methods vs Phlex components
The form builder (f) and Phlex components can be mixed freely in a
form. Builder methods are convenient for one-offs; Phlex components give
you typed props, consistent styling, and integrated labels:
|
|
In KanbanFlow we use Phlex components for all inputs and the Button
component for submit.
A minimal working form
Before building the primitives, confirm form_with works end to end.
Add new and create to the boards controller:
|
|
Temporary: @board.user = User.first is a placeholder until Module 11 adds authentication. At that point this line is replaced with @board.user = current_user. Make sure you’ve run bin/rails db:seed so a user exists.
And a minimal view using builder methods directly:
|
|
Note that we use a plain button element rather than f.submit for
the submit button. f.submit renders an <input type="submit"> which
is less flexible for styling. A button(type: "submit") renders a
<button> element and accepts a content block — consistent with how
we use Button components throughout the app.
Visit http://localhost:3000/boards/new. The form should render and
submit correctly. In Lesson 4 we replace the inline builder fields with
Phlex primitives.