Adonis入門 #2(DB操作編)
2019/07/18

前回は、Adonis入門(導入編)ということで、AdonisJsを立ち上げてRouteを操作する方法を学びました。

今回は、DB(mysql)に接続してテーブルの作成からデータの挿入・取得・削除をしてみようと思います。

事前に

mysqlを使うので、起動しておいてください。

DBへの接続設定

公式リファレンス

/config/database.jsがDBの設定ファイルになっています。

すでにmysqlへの接続設定は書かれているため、環境変数で接続先を設定するだけで接続することができます。

AdonisJsでは、環境変数の設定にdotenvを採用しています。ですので、ルートディレクトリにある.envの以下の部分を編集します。

DB_CONNECTION=mysql  # ここで接続するDBにmysqlを選択
# DBの設定に合わせて値を変えてください
DB_HOST=127.0.0.1
DB_PORT=3336
DB_USER=adonis
DB_PASSWORD=adonis
DB_DATABASE=adonis

DBへの接続

AdonisからDBにアクセスするために、mysqlパッケージをインストール

$ yarn add mysql
もしくは
$ yarn add mysql2

もし、mysql2を使う場合は、config/database.jsの修正する必要があります。

...
mysql: {
    client: 'mysql2',   // ⇐ ここを変更
    connection: {
...

DBに接続ができているか確認してみます。
start/routes.jsに以下のrouteを追加

Route.get('/db', async () => {
  return await Database.table('users').select('*')
})

もちろん、データベースの中身が空っぽなので、以下のように表示されます。

adonis1-1

別のエラーが起こるようであれば、DBの接続設定が間違っている可能性があるので、見直してください。

Modelを使ったテーブルの作成

続いては、TODOアプリを作りたいので、まずはTODO用のテーブルを作成します。

ModelとMigrationファイルの作成

$ adonis make:model Todo --migration
✔ create  app/Models/Todo.js
✔ create  database/migrations/1561644221251_todo_schema.js

--migrationを付けると、モデルの作成と一緒にマイグレーションファイルも作成してくれます。

作成された段階ではこんな感じ。

'use strict'

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')

class TodoSchema extends Schema {
  up () {
    this.create('todos', (table) => {
      table.increments()
      table.timestamps()
    })
  }

  down () {
    this.drop('todos')
  }
}

module.exports = TodoSchema

すでにincrementstimestampsが定義されています。
incrementsはプライマリキーであるidを自動で加算してくれます。
timestampsはcreated_atとupdated_atを自動付与してくれます。

Migration設定

作成されたマイグレーションファイルにTodoテーブルの内容を書いていきます。

カラムは、タイトル・詳細内容・完了ステータス。

Migrationの詳しい使い方は、公式リファレンスを参照

'use strict'

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')

class TodoSchema extends Schema {
  up () {
    this.create('todos', (table) => {
      table.increments()
      table.timestamps()
      table.string('title').notNullable()
      table.text('content')
      table.boolean('done')
    })
  }

  down () {
    this.drop('todos')
  }
}

module.exports = TodoSchema

タイトル(title)は、絶対に入力されている必要があるので、notNullableを付けてnullの状態を禁止にしました。
詳細内容(content)は、text型、完了ステータス(done)は、boolean型で定義しました。

Migration実行

TODOテーブルを定義できたので、Migrationを実行してDB上にテーブルを作成します。

$ adonis migration:run
migrate: 1503250034279_user.js
migrate: 1503250034280_token.js
migrate: 1561644221251_todo_schema.js
Database migrated successfully in 1.97 s

Migrationが完了しました。
TODO以外にも、デフォルトで作成されていたuserとtokenモデルもMigrationされました。

テーブルが作成されたかをmysqlから確認します。

adonis1-2

定義した通り、TODOテーブルが作成されていました。

データの作成・取得・更新・削除

作成したTODOテーブルをAdonisから操作してみます。

make:modelした際に、TODOモデル(app/Models/Todo.js)が作成されているので、それを利用して操作していきます。

データの作成

TODOを作成して、データをjsonを返すルートを作成します。

const Todo = use('App/Models/Todo')

Route.get('/todo/add', async () => {
  const todo = new Todo()
  todo.title = 'はじめてのTODOアイテム'
  await todo.save()
  return todo;
})

titleが「はじめてのTODOアイテム」であるTodoを作成して保存しているシンプルなコードです。

http://127.0.0.1:3333/todo/add にアクセスして、作成されたことが確認できます。

adonis1-3

データの取得

作成したTODOの一覧を取得します。

Route.get('/todo', async () => {
  return await Todo.all();
})

adonis1-4

TODOの中からidで一つだけ取得するには、

Route.get('/todo/:id', async ({ params }) => {
  const { id } = params;
  return await Todo.find(id)
})

データの削除

id=1のデータを削除してみましょう。

Route.get('/todo/:id/delete', async ({ params }) => {
  const { id } = params;
  const todo = await Todo.find(id)
  return await todo.delete()
})

adonis1-5

一覧を取得して確認すると、id: 1がなくなっていますね。

adonis1-6

まとめ

DBに接続して、簡単な操作を行いました。

次回は、モデルを使って実際の運用を想定した、タイトルでの検索であったり、doneカラムで完了・未完了のフィルタリングに挑戦します。

リレーションを使ってTODOにメッセージを追加できるようにしてみようと思います。