前提・実現したいこと
Laravelでお気に入り機能(ajax)を実装したのですが、クエリの数を減らしたいです。
仕様としては、投稿に対してログインユーザーがお気に入り登録をし、既にお気に入り登録していれば、
お気に入り解除、そうでなければ登録という機能となっています。
発生している問題・エラーメッセージ
以下のようなクエリが投稿の数だけ発行されてしまいます。
sql
1select exists(select * from `posts` inner join `favorites` on `posts`.`id` = `favorites`.`post_id` where `favorites`.`user_id` = 6 and `post_id` = 106) as `exists` 2select exists(select * from `posts` inner join `favorites` on `posts`.`id` = `favorites`.`post_id` where `favorites`.`user_id` = 6 and `post_id` = 105) as `exists` 3select exists(select * from `posts` inner join `favorites` on `posts`.`id` = `favorites`.`post_id` where `favorites`.`user_id` = 6 and `post_id` = 104) as `exists` 4...略
⬇️ このようにしたい?
sql
1select exists(select * from `posts` inner join `favorites` on `posts`.`id` = `favorites`.`post_id` where `favorites`.`user_id` = 6 and `post_id` = IN(104,105,106...) as `exists`
該当のソースコード
// Postコントローラー public function index() { $posts = Post::all(); return view('posts.index', compact('posts')); }
php
1viewの以下の箇所で発生しています。 2@foreach($posts as $post) 3(省略) 4@auth 5 @if (Auth::id() !== $post->user->id) 6 @if (Auth::user()->is_favorite($post->id)) // ここで発生 7 <button class="btn btn-warning btn-sm favorite mt-3" data-postid="{{ $post->id }}" data-or_favorite="unfavorite">お気に入り解除</button> 8 @else 9 <button class="btn btn-success btn-sm favorite mt-3" data-postid="{{ $post->id }}" data-or_favorite="favorite">お気に入り登録</button> 10 @endif 11 @endif 12@endauth 13@endforeach 14
php
1Userモデル 2 3 // リレーション 4 public function favorites() 5 { 6 return $this->belongsToMany(Post::class, 'favorites', 'user_id', 'post_id'); 7 } 8 9 /** 10 * 既にお気に入り登録してるか 11 * 12 * @param [int] $postId 13 * @return boolean 14 */ 15 public function is_favorite($postId) 16 { 17 return $this->favorites()->where('post_id', $postId)->exists(); 18 }
php
1 Postモデル 2// リレーション 3public function user() 4{ 5 return $this->belongsTo(User::class); 6}
調べたこと
クエリの発行数を減らす方法として「eagerロード」という方法がありますが、今回のようなケースの場合、どのように記述すれば良いかわかりませんでした。初心者ゆえ、おかしな質問をしていたら申し訳ありません。
補足情報(FW/ツールのバージョンなど)
Laravel7
回答1件
あなたの回答
tips
プレビュー