Seeders
Seeders fill your database with starter data — the admin account, demo users, sample catalogue rows, anything you want on a fresh install. In Grit, every resource gets its own seeder file, you can generate one in a single command, and --faker fills it with realistic rows (relationships included).
How it fits together
There is one thin Seed() runner that calls a Seed<Resource> function per resource. Each of those lives in its own file under internal/database/, so a seeder is always easy to find and edit — including the built-in users and blogs.
seed.go ← Seed(db): the runner│├─ SeedUsers(db) → users_seeder.go (admin + demo users)├─ SeedBlogs(db) → blogs_seeder.go (sample posts)├─ SeedCategories(db) → categories_seeder.go└─ SeedProducts(db) → products_seeder.go▲└─ grit generate seeder / --seed adds theseseed_helpers.go ← pickID / firstID (relationship helpers)
When you generate a seeder, Grit writes the <resource>_seeder.go file and registers its call in seed.go at the // grit:seeders marker. You never wire anything by hand.
Running seeders
After migrating, run every seeder with one command from anywhere in the project:
$grit seed
Seeders are idempotent — each checks whether its table already has rows and skips if so, so re-running never duplicates data.
Seeding database...Created admin user: admin@example.com / admin123Created user: jane@example.com / admin123Created blog: "Getting Started with Grit" (published)Seeded 8 categorySeeded 60 productDatabase seeded successfully.
Generating a seeder
Add a seeder to a resource you already generated — it reads the model to pre-fill one example record with the right field types:
$grit generate seeder Customer
Pass more than one, or emit the seeder at the same time you scaffold the resource with --seed:
$grit generate seeder Customer Order Product$grit generate resource Tag --fields "name:string" --seed
Filling rows with faker
Without a flag you get one editable example row. Add --faker (and --count N, default 10) to instead generate a loop that fills many rows with gofakeit. It ships inside the API, so this works offline.
$grit generate seeder Product --faker --count 60
Values are chosen from each field's name and type:
| Field | Faker value |
|---|---|
| name | gofakeit.Name() |
| gofakeit.Email() | |
| phone / city / company | gofakeit.Phone() / City() / Company() |
| float (price) | gofakeit.Price(1, 1000) |
| int / uint | gofakeit.Number(1, 100) |
| bool | gofakeit.Bool() |
| date / datetime | gofakeit.Date() |
| file:image / files:image | a sample picsum image URL |
Anything the guesser doesn't recognise falls back to gofakeit.Word(). It's just Go — open the file and swap in your own calls.
Relationships
This is the part most seeders get wrong. A belongs_to field (a Product's Category, say) needs a real parent id, not a random string. Grit handles it: the seeder loads the parent ids once and links each row to one of them — a random parent for faker, the first parent for the static example.
func SeedProducts(db *gorm.DB) error {// ... skip if already seeded ...// Link each row to an existing parent (loaded once).var categoryIDs []stringdb.Model(&models.Category{}).Pluck("id", &categoryIDs)const n = 60for i := 0; i < n; i++ {r := models.Product{Name: gofakeit.Name(),Price: gofakeit.Price(1, 1000),CategoryID: pickID(categoryIDs), // ← a real, existing category}db.Create(&r)}return nil}
Seed order matters. A child can only link to a parent that already exists, so seed parents first. The runner calls seeders in the order you generated the resources — generate Category before Product and you're set. Need a different order? Reorder the calls in seed.go.
Editing a seeder
A static seeder is a plain slice of model structs — edit the values, add rows, done:
func SeedCategories(db *gorm.DB) error {var count int64db.Model(&models.Category{}).Count(&count)if count > 0 {return nil // already seeded}records := []models.Category{{Name: "Sample Name"}, // ← edit these// {Name: "Phones"}, // ← or add your own// {Name: "Accessories"},}for _, r := range records {db.Create(&r)}return nil}
Command reference
| Command | Does |
|---|---|
| grit seed | Run every seeder |
| grit generate seeder X [Y…] | Add a seeder to existing resource(s) |
| grit generate resource X … --seed | Emit the seeder while scaffolding |
| … --faker --count N | Fill N rows with gofakeit instead of one example |
