Snippets · v0.7.3
resource
htmx CRUD for one model (notes: title, body): the files g resource writes, split per action, public
- Commands
cargo offrails snippet show resource # read it: the README, every file, every wire cargo offrails snippet add resource # copy and wire it (--as <model> renames note) cargo offrails snippet remove resource # take it back- Needs
- nothing
- Used by
- public-show-by-slug
- Files
migration/src/m20261018_000100_create_notes.rssrc/controllers/notes/destroy.rssrc/controllers/notes/edit.rssrc/controllers/notes/index.rssrc/controllers/notes/mod.rssrc/controllers/notes/new.rssrc/controllers/notes/show.rssrc/models/note/mod.rssrc/models/note/params.rssrc/models/note/queries.rssrc/routes/notes.rssrc/views/notes.rstemplates/notes/_form.htmltemplates/notes/edit.htmltemplates/notes/index.htmltemplates/notes/new.htmltemplates/notes/show.htmltests/app/factories/note.rstests/app/notes/mod.rstests/app/notes/model_test.rstests/app/notes/read_test.rstests/app/notes/write_test.rs
- Wires into
migration/src/lib.rsat samples: migration modsmigration/src/lib.rsat samples: migrationssrc/models/mod.rsat samples: model modssrc/models/mod.rsat samples: model aliasessrc/controllers/mod.rsat samples: controller modssrc/views/mod.rsat samples: view modssrc/routes.rsat samples: route modssrc/routes.rsat samples: routessrc/routes.rsat samples: pathssrc/routes.rsat samples: route tablestemplates/shared/_nav.htmlat samples: nav linkssrc/controllers/meta.rsat samples: sitemap pathstests/app/factories.rsat samples: factoriestests/app/main.rsat samples: test mods
.offrails/template/snippets/resource/README.md
Snippet: resource
TL;DR
- htmx CRUD for one model: list, show, new/create, edit/update, delete, for
notes(title,body), public (no accounts needed).- It is the code
cargo offrails generate resource notes title:string body:text --publicwrites, as plain files: read it, copy it, rename it. A test in offrails-gen keeps the two the same.cargo offrails snippet add resource --as articlecopies it asarticles(one-word names; for others, run the generator).
When to use it
- You want to see, or start from, exactly what a scaffolded resource is, file by file, before deciding whether to run the generator.
- A small public CRUD (an internal tool, a demo, a list nobody owns). Records that belong to users want the generator with accounts installed (
find_for, tenancy tests); the generator writes those, this snippet doesn't. - Not for: a JSON API (
g api), pages without a table (g controller,g page).
Files
| Path | What it is |
|---|---|
migration/src/m20261018_000100_create_notes.rs | the table: id (64-bit), title, body, timestamps |
src/models/note/mod.rs | the entity, its relations, its label; re-exports the two below |
src/models/note/params.rs | NoteParams (the form, all strings) → validate() → NewNote, with unit tests |
src/models/note/queries.rs | find, all (paged), choices, create, update, destroy |
src/controllers/notes/{mod,index,show,new,edit,destroy}.rs | one file per action pair |
src/views/notes.rs | NoteView (display strings) and the page structs |
src/routes/notes.rs | the router, paths::notes(), paths::note(id)…, the ROUTES rows |
templates/notes/{index,show,new,edit,_form}.html | the pages, in the template's tokens (every dark: partner) |
tests/app/notes/{mod,read_test,write_test,model_test}.rs | request tests (happy paths, 422, escaping, N+1, a huge ?page) and the queries on both databases |
tests/app/factories/note.rs | factories::note(db), note_params, note_with, reload_note |
Wiring
One line at each anchor, marked // notes ({# notes #} in the nav):
migration/src/lib.rsatsamples: migration modsandsamples: migrationssrc/models/mod.rsatsamples: model mods(pub mod note;) andsamples: model aliases(pub type Note)src/controllers/mod.rsatsamples: controller mods,src/views/mod.rsatsamples: view modssrc/routes.rsatsamples: route mods,samples: routes,samples: paths,samples: route tablestemplates/shared/_nav.htmlatsamples: nav links,src/controllers/meta.rsatsamples: sitemap pathstests/app/factories.rsatsamples: factories(two lines),tests/app/main.rsatsamples: test mods
After adding
cargo run -q -- db migrate, then provedown():cargo run -q -- db rollback && cargo run -q -- db migrate.bin/tailwindcss -i assets/app.css -o static/app.css --minify(the pages' classes;bin/devdoes it live).- Write
product/features/notes.mdand cite its AC ids on the tests; thencargo offrails verify.
Adapting it
- Every
// APP:line is a decision: what a note is, the validation limits (params.rs), the label, what each page shows. - More fields: a migration (
cargo offrails g migration add_x_to_notes x:string), then the entity,NoteParams,validate(), the form and the factory. The generator does all of that at once for a new resource. - SECURITY: public means anyone can create, change and delete. Before real data, add accounts and scope it (
find_for), or regenerate it with the generator.
Remove it
cargo offrails snippet remove resource (with --as <model> if you added it so) deletes the files you didn't change and the marked lines; it lists what it kept. By hand: delete the paths above and every line marked // notes. Roll the migration back first if it ran (cargo run -q -- db rollback).