トップページ
Laravel学習サイトLaravelやるばい

目次

リレーションでEagerロードを使う方法

今回はEagerロードについての解説です。

今回の解説に当たってDBへのアクセス状況を調べますが「Laravel-debugbar」という物を導入します。

導入方法を知らない方は下記の記事を参考に導入して下さい。

https://newsite-make.com/laravel-debugbar/


Eagerロードとは何か

ECサイト作成の解説の記事を使います。

商品をカートに追加してカートのページにアクセスしてLaravel-debugbarのQueriesの項目を見ます。(下記では商品を2つカートに追加しています)

20250309_192430_eager-load1.jpg

下記の赤枠に注目します。

20250309_192738_eager-load2.jpg

赤枠の部分はカートに追加した商品が格納されているテーブル(stocksテーブル)にアクセスしているという意味です。

青枠の部分はカートに追加した商品情報を表示するのにかかった時間です。

リレーションをするとこのように1つ1つの商品を表示するのに時間を必要とします。

上記の例は商品が2つだからDBへの負荷がないですがカートにいっぱい商品があったり多くの人がアクセスした時を考えるとDBへの負荷がとんでもないことになります。

DBへの負荷が凄くなるのを防ぐ為にリレーションをする時には必ずEagerロードを使います。


Eagerロードの記述

ECサイト作成の記事のコードで説明します。

リレーションをしているのはカートのページのテンプレートの下記のコードでした。

<div class="item-wrap">
    @forelse($carts as $cart)
        <div class="item">
            <h2>{{ $cart->stock->name }}</h2>
            <img src="{{ asset('storage/images/' . $cart->stock->image) }}" alt="">
            <p>{{ $cart->stock->price }}</p>
            <form method="post" action="{{ route('mycart.delete', ['cart' => $cart->id]) }}">
                @csrf
                @method('DELETE')
                <button class="delete-button" onClick="return confirm('本当に削除しますか?');">カートから削除</button>
            </form>
        </div>
    @empty
        <p>カートは空っぽです。</p>
    @endforelse
</div>

「{{ $cart->stock->name }}」や「{{ $cart->stock->price }}」です。

ここはそのままでよくて表示元となるCartモデルを修正します。

Cartモデルには下記の記述があります。

public static function cartIndex() {
    return Cart::where('user_id', Auth::id())->get();
}

これをEagerロードの書き方に変えます。

public static function cartIndex() {
    return Cart::with('stock')->where('user_id', Auth::id())->get();
}

「Cart::with('stock')」でEagerロードになります。

stockはリレーションしているモデル名です、最初の文字を小文字にします。

コードを変えてから再びカートのページを表示するとDBへのアクセスが1回になっているのを確認できます。

20250309_205230_eager-load3.jpg

あなたが作っているアプリにもEagerロードを導入してDBへの負荷を減らして下さい。








戻る