Follow me on Twitter: Follow @justericchapman
Model factories vs Database seeding
We have our database but no data. One way to change that would be to manually enter data directly in the database.
But what append if we delete those data and want more? It will be a big time lost to go to the database each time and also that could be a security issues.
The "pro" way to do that is to use Factories and Seeders. The difference between those is the Model Factory object is a fake Model data creator and Seeder is used when we need to create real data in one table.
An example of Model Factory will be a UserFactory that define and create one or many fake users.
An example of Database seeding is a CountrySeeder that will fill the table countries with real country names. The Seeders can then for example be run before testing phase and/or another time before deploying to production.
In ours small web app. We need to create some fake posts for testing purpose. In that case Model Factories will be our solution.
Model Factories
To create a Model Factory we need to open: database/factories/index.ts
import Factory from '@ioc:Adonis/Lucid/Factory'
import Post from 'App/Models/Post'
export const PostFactory = Factory
.define(Post, ({ faker }) => {
return {
title: faker.lorem.sentence(),
content: faker.lorem.text(),
}
})
.build()
So we create a new Factory object that define a Post fake title and fake content. This code do not create fake data it only define the way fake data will be created.
To create data we have to execute the PostFactory.create() or PostFactory.createMany(x)
For simplicity purpose we will execute that code when visiting a specific route.
Let's open the start/routes.ts file and add this route:
Route:get('/create-posts', async () => {
await PostFactory.createMany(5)
})
So when we visit the '/create-posts' route. The PostFactory will create 5 fake posts.
Good. Now open the browser and go to /create-posts that will create fake posts.
You can validate the posts creation by visiting root '/' index path to see the content of posts table.
public async index ({}: HttpContextContract) {
const posts = await Post.all()
return posts
}
That's posts raw data. Let's create a view to properly display those values
Create an Edge Template View
Adonis already include a module to render html/js template. That module is call Edge. A Edge file is a template with expression placeholder that will be replace at runtime by the expression value.
Best way to understand the concept is to create one. Under resources/views we will create a folder name post and under post a file name index.edge
resources/view/post/index.edge
@each (post in posts)
<h2>{{ post.title }}</h2>
<p>{{ post.content }}</p>
<hr>
@endeach
This html Edge template syntax will loop through posts list and for each post will display post title and post content
Last step, to display this template we have to modify our PostsController index action:
public async index (ctx: HttpContextContract) {
const posts = await Post.all()
return ctx.view.render('post/index', {posts})
}
Note the render method syntax: render(template_name, {data_object})
End of part 3
That's it for today. Stay tune for more Adonis.
The best way to miss nothing is to follow me on Twitter: Follow @justericchapman
Top comments (4)
Hi Eric, your tutorial series are great - many on topics I am pursuing. Thanks!
I followed this one and get an error when calling the PostsFactory to seed the db from the create-posts.
ReferenceError
PostFactory is not defined - on start/routes.ts
I made sure to follow steps and double checked - it seems that PostsFactory is not available to the scope of the running app - is this something that the ioc should be taking care of?
Do I need to explicitly import PostsFactory anywhere?
Thanks
Not that familiar with ioc on Adonis so I just did import explicitly at routes.ts and this worked for me:
import Route from '@ioc:Adonis/Core/Route'
import {PostFactory} from 'Database/Factories/index'
Hi , kirschd . I have a little question for you.
if we dont want to use migrations and just want to map model with databse then how will we do that ? if you have a code in git hub repo then please give me the link
Edge template integate with Alpine.js is very good solution for SPA.