4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravelでviewに共通の変数を渡す(ただし処理は一回で)

Last updated at Posted at 2021-06-24

Laravel歴1ヶ月のど素人です。

DBから取得した結果をviewに共通の変数として渡したいって時にどうしたらいいのか、
公式を参考に作ってみました。

とりあえず公式を参考に作ってみる

Laravel公式はこちら
https://readouble.com/laravel/8.x/ja/views.html

ComposerServiceProvider
namespace App\Providers;

use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider
{

    public function register()
    {
    }

    public function boot()
    {
        View::composer(
            '*', 'App\Http\View\Composers\CategoryComposer'
         );
    }
}
自前で作ったComposerクラス
namespace App\Http\View\Composers;

use App\Repositories\Category\CategoryRepository;
use Illuminate\View\View;


class CategoryComposer
{
    protected CategoryRepository $category;

    public function __construct(CategoryRepository $category)
    {
        $this->category = $category;
    }

    public function compose(View $view)
    {
        // DBからデータを取得してビューに渡す
        $view->with('category_groups', $this->category->getCategoryGroupList());
    }
}

このままサイトを表示すると・・・

image.png

N+1を検知するライブラリを仕込んでいたので、全ページで上記のアラートが出るように。。。
おそらくサイト全体のviewをパーツ化し読み込んでいるので、そのパーツをレンダリングするたびにSQLが実行されてしまっているようでした。

また、以下のQiitaを参考に実装をしてみましたが、「middlewareの仕事じゃない!」とコードレビューで指摘を受けてしまい。。。。

シングルトンにすることでSQL実行を一回に

こんな感じにすることで、同じ処理が何度も呼ばれることは無くなりました。

ComposerServiceProviderを修正
namespace App\Providers;

use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider
{

    public function register()
    {
        // 自前で作ったCategoryComposerをシングルトンに登録する
        $this->app->singleton(\App\Http\View\Composers\CategoryComposer::class);
    }

    public function boot()
    {
        View::composer(
            '*', 'App\Http\View\Composers\CategoryComposer'
         );
    }
}
自前で作ったComposerクラスをすこし改良
namespace App\Http\View\Composers;

use App\Repositories\Category\CategoryRepository;
use Illuminate\View\View;


class CategoryComposer
{

    protected $category_group;

    public function __construct(CategoryRepository $category)
    {
        // DBから取得した結果をプライベート変数に保存しておく
        $this->category_group = $category->getCategoryGroupList();
    }

    public function compose(View $view)
    {
        // 何度呼ばれてもコンストラクタで取得しておいた結果を返すようにする
        $view->with('category_groups', $this->category_group);
    }
}

おわり

ググり方が悪かったのか、なかなか解決できなかったのでqiita記事にしてみました。
別の方法が何かあればコメントもらえると嬉しいです。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?