> adonis make:seed User
You are viewing the legacy version of AdonisJS. Visit https://adonisjs.com for newer docs. This version will receive security patches until the end of 2021.
Once you’ve prepared your database schema with migrations, the next step is to add some data. This is where database seeds and factories come into the picture.
Seeds are JavaScript classes containing a run
method. Within the run
method you are free to write any database related operations your seed requires.
Like migrations, a seed file is created using the adonis make
command:
> adonis make:seed User
✔ create database/seeds/UserSeeder.js
Now open this file and type the following code inside it:
const Factory = use('Factory')
const Database = use('Database')
class UserSeeder {
async run () {
const users = await Database.table('users')
console.log(users)
}
}
module.exports = UserSeeder
Run the seed file by calling the adonis seed
command, which will execute the run
method on all existing seed files.
Since you can write any database related code inside your seed files and execute them from the command line, they are helpful in offloading some tasks from your actual application code.
However, the real power of seeds is unlocked when combined with Factories.
Factories define data structures (blueprints) used to generate dummy data.
Factory blueprints are set inside the database/factory.js
file:
const Factory = use('Factory')
const Hash = use('Hash')
Factory.blueprint('App/Models/User', async (faker) => {
return {
username: faker.username(),
email: faker.email(),
password: await Hash.make(faker.password())
}
})
When a model instance is generated from a factory blueprint, the model’s attributes are prefilled using the keys defined inside the blueprint:
const user = await Factory
.model('App/Models/User')
.create()
Many model instances can be generated at the same time:
const usersArray = await Factory
.model('App/Models/User')
.createMany(5)
Say we want to create a User
model and relate a Post
to it.
For the example below, a posts relationship must first be defined on the User model. Learn more about relationships here.
|
First, create blueprints for both models in the database/factory.js
file:
// User blueprint
Factory.blueprint('App/Models/User', (faker) => {
return {
username: faker.username(),
password: faker.password()
}
})
// Post blueprint
Factory.blueprint('App/Models/Post', (faker) => {
return {
title: faker.sentence(),
body: faker.paragraph()
}
})
Then, create a User
, make a Post
, and associate both models to each other:
const user = await Factory.model('App/Models/User').create()
const post = await Factory.model('App/Models/Post').make()
await user.posts().save(post)
You may have noticed that we used the make
method on the Post
blueprint.
Unlike the create
method, the make
method does not persist the Post
model to the database, instead returning an unsaved instance of the Post
model pre-filled with dummy data (the Post
model is saved when the .posts().save()
method is called).
Below is the list of available seed commands.
Command | Options | Description |
---|---|---|
|
None |
Make a new seed file. |
|
|
Execute seed files (you can optionally pass a comma-separated list of |
Below is the list of available methods when using Lucid model factories.
Persist and return many model instances:
await Factory
.model('App/Models/User')
.createMany(3)
Return model instance but do not persist it to the database:
await Factory
.model('App/Models/User')
.make()
Return array of model instances but do not persist them to the database:
await Factory
.model('App/Models/User')
.makeMany(3)
If your application doesn’t use Lucid models you can still use the Database Provider to generate factory database records.
To define your factory blueprint without Lucid, pass a table name as the first parameter instead of a model name (e.g. users
instead of App/Models/User
):
Factory.blueprint('users', (faker) => {
return {
username: faker.username(),
password: faker.password()
}
})
Define a different table name at runtime:
await Factory
.get('users')
.table('my_users')
.create()
For PostgreSQL, define a returning column:
await Factory
.get('users')
.returning('id')
.create()
Choose a different connection at runtime:
await Factory
.get('users')
.connection('mysql')
.returning('id')
.create()
The methods make
, makeMany
, create
and createMany
accept a custom data object which is passed directly to your blueprints.
For example:
const user = await Factory
.model('App/Models/User')
.create({ status: 'admin' })
Inside your blueprint, your custom data object is consumed like so:
Factory.blueprint('App/Models/User', async (faker, i, data) => {
return {
username: faker.username(),
status: data.status
}
})
The faker
object passed to a factory blueprint is a reference to the Chance random generator JavaScript library.
Make sure to read Chance’s documentation for the full list of available faker
methods and properties.
Since factories and seeds fit many different use cases you might be confused how/when to use them, so here is a list of frequently asked questions.
Do factories and seeds have to be used together?
No. Factories and seeds are not dependent upon each other and can be used independently. For example, you could just use seed files to import data into an AdonisJs app from a completely different app.
Can I use factories when writing tests?
Yes. Import the factory provider (Factory
) into your test and use as required.
Can I run only selected seed files?
Yes. Passing --files
with a list of comma-separated filenames to the adonis seed
command ensures only those files are run, for example:
> adonis seed --files='UsersSeeder.js, PostsSeeder.js'