💭

Laravel8(API) × Vue.js で中間テーブルにPOSTする

2022/12/08に公開

現在お知らせ機能を実装しており、「次回から表示しない」ボタンを配置しています。ユーザーごとにどのお知らせを非表示にするかを管理するために、中間テーブルを作成しています。
現状はINSERTで中間テーブルにレコードを追加しています。
Vue.jsでaxiosを使って、APIからお知らせの情報を取得&表示まで実装済。
今回はAPIを完成することをゴールとします。

Laravel8(APIモード)
Vue2(SPA)

実装手順

  • 中間テーブルのモデルを作成&関連付け
  • UserControllerで中間テーブルへPOSTする内容を記述
  • ルーティングの設定(api.php)
  • PostmanでPOSTリクエスト送信
  • Vue.jsからのリクエスト→APIとの疎通を確認

中間テーブルのモデルを作成&関連付け

多対多の中間(ピボット)テーブルのモデルを作成する場合、usingメソッドを呼び出すこと。
Notificationsモデル

public function users() {
        return $this->belongsToMany(User::class)->withPivot(['read', 'hide_next'])->using(NotificationUser::class);
    }

Usersモデル

public function notifications() {
        return $this->belongsToMany(Noification::class)->withPivot(['read', 'hide_next'])->using(NotificationUser::class);
    }

ピボットテーブル用モデル生成

php artisan make:model NotificationUser

NotificationUserモデル

<?php
namespace App\Models;

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

class NotificationUser extends Model
{
    use HasFactory;

    protected $fillable = ['id','notification_id','user_id','read','hide_next','created_at','updated_at'];
}

ちなみに、モデルを作成した際は、

protected $fillable = ['hoge'];

これは基本的には必ず必要です。
これはマスアサインメントというコンピュータの脆弱性をついて、データを盗み出す行為の対策を行うため。不正なパラメータの送信を防ぐ目的でLaravelではこれがない場合に(全部ではないかもしれないけど)エラーが発生します。
参考:https://qiita.com/yyy752/items/820260163d4883efb132

UserControllerで中間テーブルへPOSTする内容を記述

public function hidepopup(Request $request)
    {
        $data = $request->all();

        $hidepopup = NotificationUser::create($data);

        return response([ 'hidepopup' => $hidepopup, 'message' => 'Created successfully'], 200);
    }

ルーティングの設定(POSTの部分のみ抜粋)

下記を設定して、localhost:8000/api/hidepopupでアクションを実行するように処理

Route::post('/hidepopup', [UserController::class, 'hidepopup'])->middleware('auth:api');

PostmanでPOSTリクエスト送信

Untitled

[http://localhost:8000/api/hidepopup](http://localhost:8000/api/hidepopup) に対してPOSTデータを送信。
するとエラー発生。

Illuminate\Database\QueryException: SQLSTATE[42S02]: Base table or view not found: 1146 Table &#039;laravel_api.notification_users&#039; doesn&#039;t exist

テーブル名がnotification_users と複数形になっているため、そんなテーブルはないと言われていますね。
そこで、調べてみると、参照するテーブル名を変更するためには、NotificationUser テーブルで処理を行うように変更する。

protected $table = 'nottification_user';

再度PostmanでPOSTする。

{
    "hidepopup": {
        "notification_id": "17",
        "user_id": "25",
        "read": "false",
        "hide_next": "true",
        "updated_at": "2022-12-06T05:31:50.000000Z",
        "created_at": "2022-12-06T05:31:50.000000Z",
        "id": 3
    },
    "message": "Created successfully"
}

👍
とりあえずAPI側の実装は完了です。
次回はVue.jsからAPIへリクエスト送信の実装をします。

Discussion