Discover AdonisJS : Migrations, Models and Controllers
Tags: javascript, adonis, node, express
Published: 2021-03-27 18:36:52

---
title: Discover AdonisJS : Migrations, Models and Controllers
published: true
description: 
tags: javascript, adonis, node, expressjs
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2r7pwf06szmde50ryv93.png
series: AdonisJS
---
Follow me on Twitter: <a href="https://twitter.com/justericchapman?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @justericchapman</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<h2>Create Model</h2>
The model is our javascript object that interact with the database.

To create a modal we can use the ace command:
```
node ace make:model Post -cm
```
The -cm arguments tell ace to also create the controller and the migration. So one command will create 3 files:
![make model](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fu391sctb7qd16w1hd9w.png)

Let's first open our new migrations file. Under database/migrations.
```js
 public async up () {
    this.schema.createTable(this.tableName, (table) => {
      table.increments('id')
      table.timestamps(true)
    })
  }
```
The migration represent a database table definition. We don't manipulate the database directly. The migration will be use later to create and/or modify the database. 

In the migration we list columns, key and index of the table.

By default migration include an id and timestamps column.
Let's add more columns to existing ones.
```js
public async up () {
    this.schema.createTable(this.tableName, (table) => {
      table.increments('id')
      table.timestamps(true)
      table.string('title')
      table.text('content')
    })
  }
```
If we look at migration code we can see again the Adonis self descriptive, easy and clean code. table.string('title') will create a title column with a string datatype. You see my explanation is not even necessary, Adonis is really easy to understand even for newbie.

Now that the migration is created we can run this migration and create the database.

The ace command for that is:
```
node ace migration:run
``` 
That will create the database with a containing table name Posts with all the specified columns.

Note the database is located under tmp/db.sqlite3

As you guess later if we want to change the migrations files we can re-run the migration. We can also create a new migration to add more tables to the database.

<h2>Add new column to the model</h2>
Now it's time to open the model file (under app/models/Post.ts)
![post model](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tb4j0t3ipecjzhb3q3t9.png) This model will be the map between our javascript code and the database table. The Post model is automatically map to the posts table in the database.

Let's add the 2 new columns we add in the migration:
```js
import { DateTime } from 'luxon'
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'

export default class Post extends BaseModel {
  @column({ isPrimary: true })
  public id: number

  @column.dateTime({ autoCreate: true })
  public createdAt: DateTime

  @column.dateTime({ autoCreate: true, autoUpdate: true })
  public updatedAt: DateTime

  @column()
  public title: string

  @column()
  public content: text
}
```Now all the model properties have a matching table columns.

The last file created was the controller (under app/controllers/PostsController.ts)
![post controller](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r8r2mb8a0guwe7x6n6rn.png)The controller contains methods that will be call from our routes. By default Adonis create 7 public methods each one representing actions: index, create, store, show, edit, update and destroy.

Those actions will be call by our route. For example if we want to create a new Post we will create a route that will execute the PostsController create method. 

Let's do just that. Open the routes file (under start/route.ts) delete the single route and add this new one:
```js
Route.get('/', 'PostsController.index')
```
That code is very descriptive. When the user visit the root '/' Adonis will execute the index method of the PostController class.

Under PostController class index method add this code:
```js
export default class PostsController {
  public async index ({}: HttpContextContract) {
      return 'This is my Posts list'   
  }
```

Then run the server and open your browser:
```
node ace serve --watch
```
![page post index](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pkjr9on24b15138gbrh9.png)

Thats cool but we can do better. Let's modify our PostsController index method to query the database and display all posts.
```js
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Post from 'App/Models/Post'

export default class PostsController {
  public async index ({}: HttpContextContract) {
    const posts = await Post.all()
    return posts
  }
```
Again, to query the database and get all posts table content only one line of super clean code is necessary. Adonis in all his glory! No database config, no connection manager, no initialization. Cannot be easier than that.
```js
const posts = await Post.all()
```
Since there is no data in the Posts table, that will return an empty array []

<h2>End of part 2, tomorrow part 3</h2>
That's it for today. Stay tune for part 3 tomorrow. We will learn how to add posts to the database table and also how to create our first view to display those posts.

The best way to miss nothing is to follow me on Twitter: <a href="https://twitter.com/justericchapman?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @justericchapman</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>