📘

Laravel(APIモード)でControllerからModelのメソッドを呼び出したい

2022/12/10に公開

今までクエリをControllerに直接記述していましたが、Modelに移行することにしました。
Controllerでは極力指令を送るだけにして、可読性を上げることが目的です。

目次

  • 現在の実装
  • 実装したいこと
  • ControllerからModelのメソッドを呼び出す方法(実装)←ここに結論あります
  • 解説

それではやっていきます!

現在の実装

  • ユーザーテーブル(User
  • お知らせテーブル(Notificaton
  • 既読管理の中間テーブル(NotificationUser
    が今回の主役です。
    現在、ログイン時にお知らせを表示しており、表示した中に次回以降表示しないボタンを設置しています。
    チェックして閉じると、中間テーブルにリクエストがPOSTされます。
    次回お知らせを表示する際には、NotificaitonControllerにクエリビルダを直接記述し、表示制御を行っています。ここを改善するのが今回のテーマです。
    ※今回は中間テーブルを作成するためのmigrationModelの記述内容は割愛させていただきます🙇

実装したいこと

  1. NotificationControllerではメソッドの呼び出しとレスポンスのみ担当させる
  2. NotificationUserモデル(中間テーブルのモデル)でデータ取得のメソッドを作成

ControllerからModelのメソッドを呼び出す方法(実装)

先に結論です。
NotificationController.php

public function notify() {
    $notification = new NotificationUser();
    $notify_user = $notification->check_notify_user();
    $auth_user = $notification->auth_user();
         
    if(Auth::check()) {
	return response([ 'notifies' => $notify_user, 'user_id' => $auth_user, 200);
    }
}

NotificationUser.php

// 表示するお知らせを取得
public function check_notify_user() {
// 実際にはもっと複雑なクエリを書いていますが、読みにくいので省略しています。
    $query = DB::table('notifications as n')
        ->leftJoin('notification_user as nu', function ($join) {
            $join->on('n.id', "=", 'nu.notification_id')
                 ->where('nu.user_id', "=", auth()->user()->id);
        })
        ->get();

    return $query;
}

// 認証ユーザーのID取得
public function auth_user() {
    return Auth::user()->id;
}

解説

Modelについて

中間テーブルでメソッドを定義しました(理由は複数のコントローラーにメソッドを散りばめると可読性が下がると考えたため)。
public function メソッド() として、Controllerからよびだせるようにしています。
初歩的ですが、return を書いていなくて一瞬ハマってました。
check_notify_user() で表示するお知らせを取得しています。
DB:: を使う際はuse Illuminate\Support\Facades\DB; の記述が必須ですので注意してください。
auth_user() でリクエストしたユーザーを取得しています。
LaravelPassportを使用している方は、use Illuminate\Support\Facades\Auth; の記述が必要です。

Controllerについて

$notification = new NotificationUser();でNotificationUserモデルをインスタンス化しています。
$notify_user$auth_user でインスタンスからメソッドを取得しています。
あとはレスポンスの中に変数を入れてあげればOKです。

Discussion