Laravel 10 入門トップページ


目次

  1. API とプロジェクトの概要
  2. プロジェクトの作成と初期設定
  3. データベースのマイグレーション
  4. シーダによるコメントデータの登録
  5. モデルの生成
  6. リソースの生成
  7. GETメソッドを利用した個別コメント取得のAPI作成
  8. 日本語文字列の表示と日時の調整
  9. GETメソッドを利用したコメント一覧取得のAPI作成
  10. データのラップ
  11. POSTメソッドを利用したコメントの新規投稿APIの作成
  12. PUTメソッドを利用したコメント更新APIの作成
  13. DELETEメソッドを利用したコメント削除APIの作成
  14. シーダの拡張
  15. ページネーションの実装
  16. 個別コメントをコントローラで取得
  17. Postman の利用
  18. ユーザ情報を登録する
  19. Sanctum によるユーザ認証
  20. ログインとトークン
  21. コメントとユーザのリレーションシップ
  22. 新規投稿時にユーザIDを記録する
  23. コメントからユーザ名を表示するリレーションシップ
  24. ユーザからコメント一覧を取得するリレーションシップ
  25. 更新と削除の権限設定
  26. 発行済みトークンの取得
  27. トークンの有効期限
  28. レート制限
  29. 閲覧権限の緩和

Laravel で API を開発する

コメントとユーザのリレーションシップ

ここではコメントとユーザのリレーションシップを設定します.ある「コメント」は一人の「ユーザ」によって投稿され,ある「ユーザ」は複数の「コメント」を投稿することができることから,「ユーザ」と「コメント」の関係は「一対多」です.

まず,マイグレーションファイルを修正して,comments テーブルに users テーブルの ID を参照する外部キーを設定します.なお,onDelete('cascade') を設定すると,ユーザのレコードが削除されたときに,そのユーザに関連付けられたコメントのレコードが全て連鎖的に削除されます(今回はその機能を使いません).連鎖削除の詳細はこちらで確認してください.

database/migrations/yyyy_mm_dd_hhmmss_create_comments_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->id();
            $table->string('title', 255);
            $table->text('body');
            $table->unsignedBigInteger('user_id');
            $table->timestamps();

            $table->foreign('user_id')
                  ->references('id')
                  ->on('users')
                  ->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('comments');
    }
};

次にシーダを修正して全てのコメントに投稿者の情報をセットします.

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_id' => 1,
            'created_at' => '2023-10-02 10:10:10',
            'updated_at' => '2023-10-02 10:10:10'
        ]);
        DB::table('comments')->insert([
            'title' => '2つ目',
            'body' => '2つ目のコメントです!',
            'user_id' => 2,
            'created_at' => '2023-10-02 10:20:10',
            'updated_at' => '2023-10-02 10:20:10'
        ]);
        DB::table('comments')->insert([
            'title' => '<三個目>のコメント',
            'body' => 'シーダによってテストデータを設定します.',
            'user_id' => 1,
            'created_at' => '2023-10-02 10:30:10',
            'updated_at' => '2023-10-02 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-10-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-11-%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++;
        }
    }
}

データベースを一旦ロールバックして再生成,データも再び投入します.

vagrant@ubuntu2204 CommentAPI $ php artisan migrate:rollback; php artisan migrate; php artisan db:seed ⏎

   INFO  Rolling back migrations.

  2023_12_16_135311_create_comments_table .................... 30ms DONE
  2019_12_14_000001_create_personal_access_tokens_table ...... 10ms DONE
  2019_08_19_000000_create_failed_jobs_table .................. 8ms DONE
  2014_10_12_100000_create_password_reset_tokens_table ........ 8ms DONE
  2014_10_12_000000_create_users_table ........................ 8ms DONE


   INFO  Running migrations.

  2014_10_12_000000_create_users_table ....................... 24ms DONE
  2014_10_12_100000_create_password_reset_tokens_table ........ 8ms DONE
  2019_08_19_000000_create_failed_jobs_table ................. 13ms DONE
  2019_12_14_000001_create_personal_access_tokens_table ...... 19ms DONE
  2023_12_16_135311_create_comments_table .................... 24ms DONE


   INFO  Seeding database.

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

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

vagrant@ubuntu2204 CommentAPI $

データベースの comments テーブルを検索して個々のコメントに投稿したユーザの ID が設定されていること確認します.

sqlite> SELECT id, user_id, created_at, updated_at, title FROM comments WHERE id < 10; ⏎
id|user_id|created_at|updated_at|title
1|1|2023-10-02 10:10:10|2023-10-02 10:10:10|最初のコメント
2|2|2023-10-02 10:20:10|2023-10-02 10:20:10|2つ目
3|1|2023-10-02 10:30:10|2023-10-02 10:30:10|<三個目>のコメント
4|1|2023-10-30 00:00:00|2023-11-25 12:29:44|佐々木 直樹
5|2|2023-10-30 00:01:00|2023-11-04 23:59:21|松本 あすか
6|3|2023-10-30 00:02:01|2023-11-24 05:12:28|渡辺 七夏
7|1|2023-10-30 00:03:01|2023-11-15 00:16:14|大垣 和也
8|2|2023-10-30 00:04:02|2023-11-13 17:01:10|石田 太一
9|3|2023-10-30 00:05:02|2023-11-24 20:30:59|鈴木 英樹
sqlite>

目次に戻る