Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Seeders and factories

An empty blog is awkward to develop: to check the list or the pagination you need posts. A seeder is a class that writes initial data into the database. A factory describes how to create a model with random but believable values. Together they fill the database in a second.

A seeder

node ace make:seeder post

The file database/seeders/post_seeder.ts appears. Write a couple of posts into the run method:

// database/seeders/post_seeder.ts
import { BaseSeeder } from '@adonisjs/lucid/seeders'
import Post from '#models/post'
 
export default class extends BaseSeeder {
  async run() {
    await Post.createMany([
      { title: 'Welcome', body: 'The first post of the blog.', isPublished: true },
      { title: 'About the project', body: 'The blog is built with AdonisJS.', isPublished: true },
    ])
  }
}

Run all seeders:

node ace db:seed

Two posts appear in the posts table — open /posts to check.

A factory

When you need many records, writing them by hand takes long. Create a factory:

node ace make:factory post
// database/factories/post_factory.ts
import factory from '@adonisjs/lucid/factories'
import Post from '#models/post'
 
export const PostFactory = factory
  .define(Post, async ({ faker }) => {
    return {
      title: faker.lorem.sentence(),
      body: faker.lorem.paragraphs(3),
      isPublished: true,
    }
  })
  .build()

The function receives a faker object from the Faker library, which generates random texts, names and addresses. Each factory call produces new values.

A factory in a seeder

// database/seeders/post_seeder.ts
import { BaseSeeder } from '@adonisjs/lucid/seeders'
import { PostFactory } from '#database/factories/post_factory'
 
export default class extends BaseSeeder {
  async run() {
    await PostFactory.createMany(30)
  }
}

After node ace db:seed the blog has 30 posts — enough to check three pages of ten.

Create a CommentFactory the same way, then declare the relationship in the post factory:

// database/factories/post_factory.ts
import { CommentFactory } from '#database/factories/comment_factory'
 
export const PostFactory = factory
  .define(Post, async ({ faker }) => ({
    title: faker.lorem.sentence(),
    body: faker.lorem.paragraphs(3),
    isPublished: true,
  }))
  .relation('comments', () => CommentFactory)
  .build()
// database/seeders/post_seeder.ts
await PostFactory.with('comments', 3).createMany(10)

You get 10 posts with three comments each. The factory fills in the postId foreign key itself.

Recreating the database

To start from a clean database, one command is handy:

node ace migration:fresh --seed

It drops all tables, applies the migrations again and runs the seeders.

Common mistake

db:seed runs all seeders on every call, so running it again adds the same posts once more. During development recreate the database with migration:fresh --seed. And never run seeders with test data on the production server.

Thanks for reading!

Donate to the site — we work hard for you.