Short form vs long form (inline --fields vs YAML --from)
When each shines, and exactly what the long form lets you express that the short form can't.
You've been mixing them all chapter β the inline --fields "β¦" form for quick resources, the --from x.yaml form when you needed default: or unique: on a belongs_to. This lesson is the explicit comparison: when each one earns its keep, and which one you reach for in which situation.
The same resource, both ways
Here's a realistic Article resource β title with slug, hero image, formatted body, status with a default β written in both forms side-by-side.
Short form (inline --fields)
$grit generate resource Article \$ --fields "title:string,slug:slug,cover:string,body:richtext,published:bool"
Long form (YAML)
name: Articlefields:- name: titletype: stringrequired: true- name: slugtype: slugslug_source: title- name: covertype: string # URL heuristic β VARCHAR(500)- name: bodytype: richtext- name: statustype: stringdefault: draft # β only YAML can set defaults- name: publishedtype: booldefault: false
$grit generate resource Article --from article.yaml
Both produce the same 8 generated files except the YAML version also sets the database defaults (status = 'draft', published = false) and is committed into the repo β which means the next teammate who pulls can regenerate the resource from scratch by re-running the same command.
What each form supports
| Feature | Inline --fields | YAML --from |
|---|---|---|
| All 13 field types | β | β |
required / optional / unique | β | β |
default values | β | β |
unique on a belongs_to (one-to-one) | β | β |
Slug slug_source override | β (third colon) | β (explicit key) |
| Re-runnable / version-controllable | Sort of (commit message) | β (committed file) |
| Comments next to each field | β | β |
| Reads cleanly past 5 fields | β (one long line) | β |
YAML field reference β the full spec
Each field entry under fields: accepts seven keys. Most have inline equivalents β two don't:
- name: <field_name> # camelCase or snake_case β requiredtype: <field_type> # one of the 13 types β requiredrequired: true|false # default depends on type (string=true, others=false)unique: true|false # adds DB unique index. Works on belongs_to (1-to-1!).default: <value> # DB default. YAML-only.slug_source: <field_name> # for type: slug β which field to slugify fromrelated_model: <ModelName> # for type: belongs_to or many_to_many β what it points at
That's the whole long-form vocabulary. The inline form compresses the first four into colons (name:type:modifier) and uses the third colon-separated slot for slug_source / related_model:
| Inline | YAML equivalent |
|---|---|
| name:string | { name: name, type: string, required: true } |
| phone:string:optional | { name: phone, type: string, required: false } |
| email:string:unique | { name: email, type: string, required: true, unique: true } |
| slug:slug:sku | { name: slug, type: slug, slug_source: sku } |
| group:belongs_to:Group | { name: group, type: belongs_to, related_model: Group } |
| tags:many_to_many:Tag | { name: tags, type: many_to_many, related_model: Tag } |
When to reach for which
Use the short form whenβ¦
- You have 1β5 fields and no defaults.
- You're prototyping β the field list will probably change before this resource is real.
- You want the command to fit in a commit message or a chat message to a teammate.
- You're pairing live and reading the spec out loud.
Use the long form (YAML) whenβ¦
- You need
defaultvalues, or you needuniqueon abelongs_to(one-to-one). - You have more than 5 fields and the inline string stops fitting on one line.
- You want the resource spec checked into git so anyone can re-generate from scratch later. Drop
article.yamlnext togrit.config.ts. - You're generating multiple resources at once and want them all in
resources/*.yamlso a script can regenerate the lot. - The resource spec is reviewed in a PR before code is written β the YAML is the design doc and the source.
The third option β interactive
Don't forget about -i when you genuinely don't know the fields yet:
$grit generate resource Article -i
The CLI walks you through each field one prompt at a time, and at the end it shows you the equivalent --fields string. Great for pairing or for when you're still designing the model in your head.
resources/ directory full of committed YAML files for the "real" resources, and ad-hoc inline commands for prototypes and experiments. Once a prototype settles, copy the inline command into a YAML and commit it.Quick check
Try it
Take this five-field resource and write it both ways in your notes.md, then actually generate it once using YAML:
- Resource: Project
nameβ string, required, uniqueslugβ auto-generated fromnamedescriptionβ text, optionalstatusβ string with defaultactivearchivedβ bool with defaultfalse
Save the YAML as project.yaml, run grit generate resource Project --from project.yaml, then grit migrate. Confirm in the admin panel that a new Project starts with status = active and archived = false without you typing them.
What's next
You can now write any field shape Grit supports in either form. One last topic for the chapter: grit sync β what to run after you edit a Go struct by hand so the TypeScript types catch up.
Spot a typo? Have an idea?
Help us improve this lesson. One click opens a GitHub issue with the lesson URL pre-filled β suggest clearer wording, report a bug, or request more depth. The course keeps improving thanks to learners like you.
Suggest an improvement on GitHub