Guide

The field API

field(name, *modifiers, **options) renders label + input + error/hint in one call.

The primary verb#

field wraps a labeled control around the right input for the attribute, wiring name, id, value, required, and the error state from the bound model:

f.field :email                          # type=email, label auto, required inferred
f.field :notify                         # boolean column → toggle
f.field :role                           # AR enum → select, humanized
f.field :bio, as: :textarea, rows: 6    # explicit as: always wins
f.field :name, :primary, :lg, label: "Full name", hint: "As on your ID"

Positional symbols are daisyUI variants (:primary, :lg, :ghost, …) stacked onto the inner input — see Variants — or a type override (:number, :date, …). Remaining keywords pass through to the input element (rows:, placeholder:, data:, …).

Options#

OptionEffect
label:Label text. Defaults to the model's humanized attribute name. label: false omits the label.
hint:Help text shown beneath the field when there is no error.
as:Override the control: :select, :textarea, :toggle, :checkbox, :file, :radio, :hidden, :rich_textarea, or any text-like type.
required:Force the required flag. Otherwise inferred from the model's unconditional presence validators.
choices:Choices for a select — implies as: :select when given. Pairs, flat values, or a Hash (optgroups).
validate:Client-side validation override: false opts out, a Hash gives explicit rules. See Client-side validation.

Everything not listed flows to the input. Caller options always beat inferred attributes — pass maxlength: 10 and the validator-derived maxlength is replaced.

Labels, errors, and hints#

The label text comes from human_attribute_name when the model speaks ActiveModel, so your locale files apply. A field whose attribute has an unconditional presence validator renders a required marker and the required attribute.

When the model has an error on the attribute, the field renders the first full message instead of the hint, and the input picks up the error variant automatically:

f.field :email, hint: "We never spam."
# valid:   … <p>We never spam.</p>
# invalid: … <p>Email is invalid</p>  (input gets the error variant)
An inferred association select is named by the foreign key user[country_id] but still shows errors Rails attached to :country — both names are checked.

The submit button#

submit defaults its label from the record's persistence state via i18n — Create User for a new record, Update User for a persisted one — and takes text and variants positionally:

f.submit                    # "Create User" / "Update User"
f.submit :primary, :lg      # default text, variants
f.submit "Save", :primary   # custom text + variants