Laravel8(API) × Vue.js で中間テーブルにPOSTする
現在お知らせ機能を実装しており、「次回から表示しない」ボタンを配置しています。ユーザーごとにどのお知らせを非表示にするかを管理するために、中間テーブルを作成しています。
現状は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リクエスト送信
[http://localhost:8000/api/hidepopup](http://localhost:8000/api/hidepopup)
に対してPOSTデータを送信。
するとエラー発生。
Illuminate\Database\QueryException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'laravel_api.notification_users' doesn'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