DEV Community

Cover image for Discover AdonisJS : Model Factories and Edge Template
Eric The Coder
Eric The Coder

Posted on

Discover AdonisJS : Model Factories and Edge Template

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()
Enter fullscreen mode Exit fullscreen mode

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)
})
Enter fullscreen mode Exit fullscreen mode

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
  }
Enter fullscreen mode Exit fullscreen mode


posts table
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
Enter fullscreen mode Exit fullscreen mode

This html Edge template syntax will loop through posts list and for each post will display post title and post content
edge template

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})
}
Enter fullscreen mode Exit fullscreen mode

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

Discussion (4)

Collapse
kirschd profile image
kirschd

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

Collapse
kirschd profile image
kirschd

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'

Collapse
waheedk53694017 profile image
Waheed khan

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

Collapse
frogconn profile image
frogconn

Edge template integate with Alpine.js is very good solution for SPA.