第1章 タスクリスト表示
02.データを扱う
次はタスクをデータベースから取り出して、表示できるようにしていく。(これができると、一気にWebシステムっぽさが出てくる。)
モデルクラスとマイグレーションファイル作成
モデルクラスのファイルも、コマンドで作成する。
$ php artisan make:model Task -m
Model created successfully.
Created Migration: 2018_05_06_224512_create_tasks_table
-m
オプションでマイグレーションファイルも同時に作成する。
(マイグレーションについては、後ほど説明する。)
まずはモデルクラスのファイルを確認する。
これはapp/Task.php
として生成されている。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
//
}
これが、データベースのテーブルとのやりとりを管理するクラスになる。
しかしフレームワークのおかげで、シンプルなやりとりについては何も書かなくても使える。
(Laravel
ではEloquent
というO/Rマッパーを使っており、その機能のおかげである。)
テーブルの構成は、マイグレーションファイルで定義する。
マイグレーションファイルの名前は実行日時が含まれるので、各自で異なる。
ここではdatabase/migrations/2018_05_06_224512_create_tasks_table.php
という
ファイルが生成されており、こちらに変更を加えていく。
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTasksTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->string('title', 512);
$table->boolean('executed');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tasks');
}
}
18〜19行目に「title」と「executed」というカラムを追加している。 これによって、最初に書いていた仕様を満たした状態になった。
- タスクID (非表示)
- タイトル
- 実行済みフラグ
初期データ作成
これでデータベースのテーブルの定義と、テーブルを扱うクラスは用意できた。 しかし、テストを行なうにしても、データが入っていないとどう確認して良いかわからないだろう。
そこで、seeder
という初期データ作成処理を作成して、初期データを投入してみよう。
その後に、その初期データが想定通りに入っているかどうか、という形でテーブル操作のテストを行なってみる。
早速seeder
を作成してみよう。
ここも、お約束のコマンド実行だ。
$ php artisan make:seeder TasksTableSeeder
Seeder created successfully.
これで、database/seeds/TasksTableSeeder.php
というファイルが生成された。
このファイルの中で、初期データ作成処理を実装する。 今回は、「ランダムな初期値」と「静的な初期値」を作成しておく。
<?php
use Illuminate\Database\Seeder;
class TasksTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// ランダム
DB::table('tasks')->insert([
'title' => str_random(512),
'executed' => false,
]);
// 静的
DB::table('tasks')->insert([
'title' => "テストタスク",
'executed' => false,
]);
DB::table('tasks')->insert([
'title' => "終了タスク",
'executed' => true,
]);
}
}
seeder
は「初期データ」なので、テーブルを作成する時に同時に実行されるようにしておきたい。
テーブルの作成は次に行なうマイグレーション実行で行なわれる。
このタイミングで、今回生成したseeder
が呼ばれるようにしておこう。
database/seeds/DatabaseSeeder.php
を下記のように修正する。
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$this->call(TasksTableSeeder::class);
}
}
この修正がマイグレーションで反映されるように、autoload
ファイルの更新も行なう必要がある。
(直接触ることは無いが、vendor/composer/autoload_classmap.php
というファイルが更新される。)
$ composer dump-autoload
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Package manifest generated successfully.
マイグレーション実行
では、「マイグレーション」という作業を行なってみよう。 「マイグレーション」とは、端的には、マイグレーションファイルによる(テーブルの作成を含む)データベース操作、 seederを実行し初期データの投入、を行なうものだ。
このファイルの情報を元にデータベースの状態の管理(巻き戻しなど)もできるのが、 今回は「こんなものがあるのか」程度に心に留めておいて欲しい。
$ php artisan migrate --env=testing --seed
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrating: 2018_05_06_224512_create_tasks_table
Migrated: 2018_05_06_224512_create_tasks_table
Seeding: TasksTableSeeder
実行できた。が、あっさり終わったので、本当に初期データが投入できたか不安だ。
というわけで、テストをしてみよう。
2014_10_12_000000_create_users_table
と2014_10_12_100000_create_password_resets_table
というものも
同時に実行されている。
これらは、ユーザ認証の機能で使うテーブルで、最初からマイグレーションファイルが用意されているものだ。
後々ではあるがユーザ認証機能を利用するので、ここではこのまま使っておく。
seeder
で投入した初期データの取得テスト
初期データは正しくテーブルへ投入されただろうか。
「tasks
テーブルからデータを取得するテスト」を作成して確認していこう。
今回は、--unit
というオプション付きで実行しよう。
$ php artisan make:test TaskTest --unit
Test created successfully.
今回はtests/Unit/TaskTest.php
というファイルが生成された。
--unit
オプション付きで実行した場合、先ほどとパスが異なっていることに注意しよう。
<?php
namespace Tests\Unit;
use App\Task;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class TaskTest extends TestCase
{
/**
* Get Seeder Tasks Test
*
* @return void
*/
public function testGetSeederTasks()
{
// 全件取得
$tasks = Task::all();
// 3件取得できるはず
$this->assertEquals(3, count($tasks));
// 実行完了していないものを取得
$taskNotFinished = Task::where('executed', false)->get();
// 2件取得できるはず
$this->assertEquals(2, count($taskNotFinished));
// 実行完了しているものを取得
$taskFinished = Task::where('executed', true)->get();
// 1件取得できるはず
$this->assertEquals(1, count($taskFinished));
// 「テストタスク」というタイトルのレコードを取得
$task1 = Task::where('title', "テストタスク")->first();
// 実行完了していないはず
$this->assertFalse(boolval($task1->executed));
// 「終了タスク」というタイトルのレコードを取得
$task1 = Task::where('title', "終了タスク")->first();
// 実行完了しているはず
$this->assertTrue(boolval($task1->executed));
}
}
このように、seeder
で入れたはずのデータが確認できるテストを書いていく。
細かく書くときりが無いので、明確にわかっている情報を中心に実装しておこう。
これで、テストを実行してみる。
$ vendor/bin/phpunit
PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
.. 2 / 2 (100%)
Time: 399 ms, Memory: 12.00MB
OK (2 tests, 6 assertions)
無事、成功となった。
「作成したモデルTask
から」「データベースのテーブルtasks
へ」アクセスし、
「seeder
で追加したデータ」を取得して中身をテストする、、、ということがこれでできた。