Laravel でのモデル/ファクトリー/シーダー作成

Laravel

ほとんどのフレームワークでMVCアーキテクチャを採用していますが、

LaravelでもMVCアーキテクチャを採用しています。

データベースのテーブルを操作するためのモデルクラスをテーブル毎に作成します。

また、自動テスト時に使うダミーデータ作成用のファクトリーと、

複数のレコードをまとめて一括登録するためのシーダーを作成していきます。

この記事のゴール

  • モデルを作成する(テーブル操作クラス)
  • ファクトリーを作成する(ダミーデータ生成クラス)
  • シーダーを作成する(データ一括登録クラス)

前提

  • Laravel でマイグレーションを実行しテーブル作成済

※テーブルを作成してない場合は前回の記事を参考にしてテーブルを作成してください。

これからやる作業

  • モデルの作成
  • ファクトリーの作成
  • シーダーの作成
  • シーダーの登録と実行
  • レコードの存在確認

モデルの作成

以前の記事で作成したテーブル「todos」を操作するためのモデルを作成します。

モデルはテーブル毎に一ファイルずつ作成します。

テーブル名は通常複数形ですが、モデル名は単数形にし、頭文字を大文字にします。

「todos」テーブルのモデルは「Todo」になります。

次のコマンドでモデルを作成してください。

php artisan make:model Todo

実行完了すると、フォルダ [app\Models\] の中に [Todo.php] が作成されます。

編集する必要は今のところないですが、一応ファイルの中身を確認してみましょう。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Todo extends Model
{
    use HasFactory;
}

class宣言の内容としては一切メソッドが存在していませんが、

テーブル操作に必要な一連のメソッドは敬称元のModelクラスで実装されています。

これで一通りテーブルへのレコード作成・検索・更新・削除が可能な状態です。

また「use HasFactory;」宣言により、次で作るファクトリーの使用も可能になっています。

ファクトリーの作成

では、次にダミーデータ作成クラスのファクトリーを作成していきます。

次のコマンドを実行してファクトリーを作成してください。

※大文字小文字は区別されます。

php artisan make:factory TodoFactory

完了すると、フォルダ [database\factories\] の中に [TodoFactory.php] が作成されます。

このファイルを開いて次のように、20行目と21行目を追記して保存してください。

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Todo>
 */
class TodoFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'todo' => fake()->text(20),
            'done' => fake()->numberBetween(0, 1),
        ];
    }
}

これでファクトリーの作成ができました。

このファクトリーは通常、モデル経由で使用します。

次に作成するシーダーで使用します。

シーダーの作成

サービス開始時に初期データを登録しておきたいテーブルや、

自動テスト時にダミーデータを一括登録しておきたい時などに、

シーダーを作成しておくと便利です。

次のコマンドでシーダークラスを作成します。

php artisan make:seeder TodoTableSeeder

完了すると、フォルダ [database\seeders\] の中に、[TodoTableSeeder.php] が作成されます。

このファイルを次のように編集して保存してください。

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Todo;

class TodoTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        Todo::factory()->create(['todo' => 'Aプロジェクト巻取改修', 'done' => 0]);
        Todo::factory()->create(['todo' => 'Bプロジェクト総合テスト', 'done' => 0]);
        Todo::factory()->create(['todo' => 'Cプロジェクト仕様変更対応', 'done' => 1]);
    }
}

追記したのは、7行目の「App\Models\Todo;」と、

16行目~18行目の「Todo::factory->create();」の部分です。

先程、ファクトリーはダミーデータ生成クラスと書きましたが、

create() メソッドにハッシュ配列でデータを渡すと、

factory() で生成されるダミーデータをハッシュ配列で上書きできます。

筆者は自動テスト時にこの手法をよく使います。

シーダーの登録

シーダーは作成したままの状態では孤立した存在なので、

一括登録コマンド実行時、他のシーダーとまとめて実行できるよう

登録しておく必要があります。

フォルダ [database\seeders\] 内にある、[DatabaseSeeder.php] を開いて

次のように編集して保存してください。21行目に追記をしています。

<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        // \App\Models\User::factory(10)->create();

        // \App\Models\User::factory()->create([
        //     'name' => 'Test User',
        //     'email' => 'test@example.com',
        // ]);
        $this->call(TodoTableSeeder::class);
    }
}

これでシーダーの登録は完了です。

シーダーの実行

次のコマンドでシーダーを実行することができます。

php artisan migrate --seed

これでデータが登録されている筈です。

データベースに接続して確認してみましょう。

確認の仕方はphpMyAdminやA5SQL Mk2等、色々ありますが、

せっかくなので、MySQL CLIで接続してコマンドで確認していきましょう。

sail-shell に接続している状態で次のコマンドを入力してください。

mysql -h mariadb -u sail -p

次のコマンドでデータベース一覧を確認します。

show databases;

データベースを選択します。

use webapp;

テーブル一覧を確認します。

show tables;

todos テーブルのレコードを表示します。

select * from todos;

文字化けしてますが、一応登録されていることが確認できました。

文字化けの原因は、諸々の文字コード設定が「latin1」になっているせいです。

次のコマンドで確認できます。

show variables like 'character_set%';

ここでいくつかの文字コード設定が「latin1」になっているのがわかりますね。

データ自体はutf8で正常に登録されています。

気持ち悪いのでどうしても日本語を表示させたい場合は次のようにしてください。

set character_set_results='utf8mb4';

ここで再度、レコード表示させてみると日本語で表示されます。

select * from todos;

「\q」コマンドを入力してデータベースの接続を切断しましょう。

以上で作業完了です。

お疲れさまでした。

コメント

タイトルとURLをコピーしました