Laravel 10 入門トップページ


目次

  1. 全体の概要
  2. Laravel によるユーザ認証
  3. ユーザ認証を備えたコメント掲示板の開発
    1. 概要
    2. データベースのマイグレーション
    3. シーダによるコメントデータの登録
    4. モデルとコントローラの生成
    5. ルートの定義と確認
    6. 未検証ユーザの動作検証
    7. コメントの一覧表示
    8. ナビゲーションメニューの追加
    9. コメント一覧の Tailwind CSS によるスタイリング
    10. コメントの詳細ページ
    11. リレーションシップの設定と投稿者名の表示
    12. ページネーションの作成
    13. コメントの投稿
    14. コメントの編集
    15. コメントの削除
    16. ナビゲーションのハイライトを調整
  4. マルチ認証の実現

Laravel でユーザ認証とマルチ認証を実現する

ユーザ認証を備えたコメント掲示板の開発

シーダによるコメントデータの登録

テスト用にコメントデータをデータベースに登録する作業を行います.例によってシーダを次のコマンドで生成します.

vagrant@ubuntu2204 laravelAuth $ php artisan make:seeder CommentsTableSeeder ⏎

   INFO  Seeder [database/seeders/CommentsTableSeeder.php] created successfully.

vagrant@ubuntu2204 laravelAuth $

生成されたシーダにテストデータを設定します.コメント一つひとつに投稿者の user_id を設定していることを確認してください.また,43行目以降で97件のランダムなデータを登録していますが,user_id がローテンション(ラウンドロビン)しており,投稿日時 created_at は ID 順に,更新日時 updated_at はランダムになっていることにも注意してください.

database/seeders/CommentsTableSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class CommentsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        // 一旦中身を削除する
        DB::table('comments')->delete();

        DB::table('comments')->insert([
            'title' => '最初のコメント',
            'body' => 'user_a の最初のコメントです!',
            'user_id' => 1,
            'created_at' => '2023-08-01 10:10:10',
            'updated_at' => '2023-08-01 10:10:10'
        ]);

        DB::table('comments')->insert([
            'title' => '2つ目',
            'body' => 'user_a の2つ目のコメントです!',
            'user_id' => 1,
            'created_at' => '2023-08-01 10:20:10',
            'updated_at' => '2023-08-01 10:20:10'
        ]);

        DB::table('comments')->insert([
            'title' => '<user_b>のコメント',
            'body' => 'シーダによってテストデータを設定します.',
            'user_id' => 2,
            'created_at' => '2023-08-01 10:30:10',
            'updated_at' => '2023-08-01 10:30:10'
        ]);

        $i = 0;
        while ($i < 97) {
            $user_id = ($i % 3) + 1;   // user_id は 3で割った余りに1を加える
            // created_at がID順になるような値を作る
            $s = floor($i / 2);    // 秒
            $m = $i % 10;          // 分   10で割った余り
            $h = floor($i / 10);   // 時
            $format = '2023-08-30 %02d:%02d:%02d';
            $created_at = sprintf($format, $h, $m, $s);
            // updated_at はランダムに
            $s = rand(0,59);
            $m = rand(0,59);
            $h = rand(0,23);
            $d = rand(1,30);
            $format = '2023-09-%02d %02d:%02d:%02d';
            $updated_at = sprintf($format, $d, $h, $m, $s);
            DB::table('comments')->insert([
                'title' => fake()->name(),
                'body' => fake()->address() . " / " .  fake()->unique()->safeEmail(),
                'user_id' => $user_id,
                'created_at' => $created_at,
                'updated_at' => $updated_at
            ]);
            $i++;
        }
    }
}

DatabaseSeeder.php には CommentsTableSeeder を実行するための処理を記載します.この時,UsersTableSeeder と CommentsTableSeeder の実行順序に注意してください.もしも CommentsTableSeeder を先に実行してしまうと,users テーブルにはまだデータが投入されていないので,comments テーブルの user_id が参照制約(外部キー制約)に違反することになり,テストデータの登録に失敗します.したがって,DatabaseSeeder でシードの実行順序を管理できることになります.(一方でマイグレーションはマイグレーションファイルに生成日時が含まれているので,生成順に実行されます.)

database/seeders/DatabaseSeeder.php
<?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(UsersTableSeeder::class);
        $this->call(CommentsTableSeeder::class);
    }
}

今設定したテストデータをデータベースに投入します.すでに users テーブルにはデータが投入されているので,シーダファイルを指定してそのシーダだけ実行する方法が考えられます.しかし,一旦全てリセットして投入し直しても良いでしょう.この時,ロールバックを複数回実行しなければならないことがあるので注意してください.

vagrant@ubuntu2204 laravelAuth $ php artisan migrate:status ⏎

  Migration name ..................................... Batch / Status
  2014_10_12_000000_create_users_table ...................... [1] Ran
  2014_10_12_100000_create_password_reset_tokens_table ...... [1] Ran
  2019_08_19_000000_create_failed_jobs_table ................ [1] Ran
  2019_12_14_000001_create_personal_access_tokens_table ..... [1] Ran
  2023_11_03_101930_add_login_id_to_users_table ............. [1] Ran
  2023_11_04_164822_create_comments_table ................... [2] Ran

vagrant@ubuntu2204 laravelAuth $ php artisan migrate:rollback ⏎

   INFO  Rolling back migrations.

  2023_11_04_164822_create_comments_table ................. 13ms DONE

vagrant@ubuntu2204 laravelAuth $ php artisan migrate:rollback ⏎

   INFO  Rolling back migrations.

  2023_11_03_101930_add_login_id_to_users_table ............ 1ms DONE
  2019_12_14_000001_create_personal_access_tokens_table .... 6ms DONE
  2019_08_19_000000_create_failed_jobs_table ............... 5ms DONE
  2014_10_12_100000_create_password_reset_tokens_table ..... 5ms DONE
  2014_10_12_000000_create_users_table ..................... 6ms DONE

vagrant@ubuntu2204 laravelAuth $ php artisan migrate:status ⏎

  Migration name ..................................... Batch / Status
  2014_10_12_000000_create_users_table ...................... Pending
  2014_10_12_100000_create_password_reset_tokens_table ...... Pending
  2019_08_19_000000_create_failed_jobs_table ................ Pending
  2019_12_14_000001_create_personal_access_tokens_table ..... Pending
  2023_11_03_101930_add_login_id_to_users_table ............. Pending
  2023_11_04_164822_create_comments_table ................... Pending

vagrant@ubuntu2204 laravelAuth $ php artisan migrate ⏎

   INFO  Running migrations.

  2014_10_12_000000_create_users_table .................... 16ms DONE
  2014_10_12_100000_create_password_reset_tokens_table ..... 4ms DONE
  2019_08_19_000000_create_failed_jobs_table ............... 8ms DONE
  2019_12_14_000001_create_personal_access_tokens_table ... 13ms DONE
  2023_11_03_101930_add_login_id_to_users_table ........... 15ms DONE
  2023_11_04_164822_create_comments_table .................. 5ms DONE

vagrant@ubuntu2204 laravelAuth $ php artisan db:seed ⏎

   INFO  Seeding database.

  Database\Seeders\UsersTableSeeder ......................... RUNNING
  Database\Seeders\UsersTableSeeder .................. 652.21 ms DONE

  Database\Seeders\CommentsTableSeeder ...................... RUNNING
  Database\Seeders\CommentsTableSeeder ............... 503.58 ms DONE

vagrant@ubuntu2204 laravelAuth $

データベースの内容を SQLite で確認します.一つひとつのコメントに user_id が設定されていること確認してください.

sqlite> .tables ⏎
comments                migrations              personal_access_tokens
failed_jobs             password_reset_tokens   users
sqlite> select * from comments; ⏎
id|title|body|user_id|created_at|updated_at
1|最初のコメント|user_a の最初のコメントです!|1|2023-08-01 10:10:10|2023-08-01 10:10:10
2|2つ目|user_a の2つ目のコメントです!|1|2023-08-01 10:20:10|2023-08-01 10:20:10
3|<user_b>のコメント|シーダによってテストデータを設定します.|2|2023-08-01 10:30:10|2023-08-01 10:30:10
4|工藤 稔|7554769  山口県佐々木市北区鈴木町津田9-5-2 / osamu30@example.net|1|2023-08-30 00:00:00|2023-09-27 14:00:09
5|大垣 直人|8365060  佐賀県西之園市北区三宅町若松1-8-3 コーポ若松109号 / miki52@example.org|2|2023-08-30 00:01:00|2023-09-08 16:12:19
6|田中 洋介|9406465  岐阜県渚市中央区佐々木町青田10-3-9 ハイツ浜田110号 / yasuhiro.sato@example.net|3|2023-08-30 00:02:01|2023-09-14 20:55:23
7|鈴木 学|2665627  宮城県渡辺市西区佐藤町渚5-9-1 ハイツ田中101号 / nakatsugawa.naoko@example.org|1|2023-08-30 00:03:01|2023-09-01 11:49:19
8|西之園 亮介|6027215  愛媛県吉田市西区村山町中村5-1-3 / pnakatsugawa@example.com|2|2023-08-30 00:04:02|2023-09-17 17:59:50

(中略)

97|笹田 加奈|6116356  宮崎県山岸市東区工藤町松本4-4-9 コーポ津田103号 / dishida@example.com|1|2023-08-30 09:03:46|2023-09-28 08:01:53
98|近藤 拓真|6815422  長野県青田市東区田中町若松6-2-1 ハイツ伊藤107号 / sato.taichi@example.net|2|2023-08-30 09:04:47|2023-09-30 02:37:29
99|宮沢 拓真|8718451  埼玉県加藤市西区斉藤町中島10-4-9 / pyamaguchi@example.com|3|2023-08-30 09:05:47|2023-09-08 03:41:48
100|若松 千代|1436078  鹿児島県三宅市東区桐山町中島3-5-9 / kato.manabu@example.net|1|2023-08-30 09:06:48|2023-09-08 05:35:58
sqlite>

目次に戻る