Laravel query()を使用してクエリの可読性を上げる

laravelを始めたての時はコントローラに直接書いていましたが、SQLが長くなると可読性が落ちてしまいます。
そんな時に使用しているのが「Repository」です。
appフォルダ内にRepositoryフォルダを作成し、その中に使用するSQLをファイルごと、メソッドごとにまとめて読みやすく、呼び出しやすく、管理しやすいようにします。
最近は業務でLaravelを目にする機会が増えてきましたが、どのシステムを見ても大体今回紹介する書き方が多いなという感じがしています。

作成手順
  • app内にRepositoryフォルダを作成
  • Repositoryフォルダ内にXXXXXRepository.phpを作成
  • 作成したファイルに必要なモデルやファサードをuseする
  • functionを作成し、SQLを書く
  • コントローラ側のコンストラクタに使用するリポジトリを宣言、クラス変数の中に格納する
  • 必要なメソッドを呼び出して、SQLを実行させる
目次

実際に作成

RepositoryフォルダとSQLファイルの作成

①まずはappフォルダ内にRepositoryフォルダを作成します
・app内で右クリックしてフォルダを作成しても良いですし、コマンドからappまで移動してmkdirコマンドから作成しても良いです

②Repository内にXXXRepository.phpを作成します

XXXRepository.phpの編集

XXXRepository.phpの中に適当なfunctionを作成して、機能にあった名前をつけます。(今回はgetUsers)
最初にクエリビルダを生成しておくことで、検索機能等の絞り込みをしたいときに検索条件を簡単に記述できるようになります。
if文でも書くことができますし、when句を使うこともできます。joinとかちょっと複雑なSQLになるとwhen使う時あるけど、単純に条件を付け加えたい時はif文でいいかなって感じがします。

<?php

namespace App\Repositories;

use App\Models\users;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class testRepository
{
    // usersテーブル取得
    public function getUsers($age) {
        // クエリログを有効化
        DB::enableQueryLog();

        // SQL
        $query = users::query(); // クエリビルダ生成
        $query->select(
            'id',
            'name',
            'age',
            'flag',
        );

        // 検索条件の適用
        if ($age != '') {
            $query->where('age', '>=', $age);
        }
        // 下記のような書き方もできます
        // $query->when($age, function ($query) use ($age) {
        //     return $query->where('age', '>=', $age);
        // });

        $results = $query->get();

        // ログに書き込み
        Log::debug(print_r(DB::getQueryLog(), true));

        return $results; // 取得結果を返す
    }
}

コントローラ側でRepository内の該当メソッドを実行

次はコントローラ側です。
クラス変数に使用したいRepositoryを格納して、使用したいメソッドを呼び出せばSQLを実行できます。
コントローラ直書きのパターンだとSQLが長くなった時に管理しづらいし、読みづらいというデメリットが出てきてしまいますのでRepositoryに別で書くのがおすすめです。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Repositories\testRepository; // XXXRepositoryをuseする
use App\Models\users;
use Illuminate\Support\Facades\Auth;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;

class BlogController extends Controller
{
    protected $testRepository;

    public function __construct(testRepository $testRepository)
    {
        $this->testRepository = $testRepository; // クラス変数に格納
    }

    public function usersList(Request $request) {
        // 初期処理
        $age = 21; // 絞り込みする場合、例として$request->input('age')で取得の想定

        // XXXRepositoryのgetUsersメソッドを使用し、ユーザ一覧を取得
        $users_list = $this->testRepository->getUsers($age)->toArray();

        return view('test', [
            'users_list' => $users_list
        ]);
    }
}

今回のテストデータと画面

ブレード側でforeachを使って$users_listを回して表示しています。
今回の例だと年齢を21以上で絞り込みしているので正しく一覧が表示されていますね。

  • URLをコピーしました!
目次