私は現在、フォローしているユーザーの投稿を取得する必要がある単純な Laravel プロジェクトに取り組んでいます。以下のコードを使用すると、投稿を取得できますが、多くの重複するクエリと、認証済みユーザーに N+1 の問題も追加します。だから、それはある種のヘッドスクラッチャーになりつつあります。他の同様のシナリオをオンラインで調べましたが、何が間違っているのかを特定できませんでした。おそらくもっと良い方法があります。現在、私は User モデルを持っています:
public function usersImFollowing()
{
return $this->belongsToMany(User::class, 'follow_user', 'user_id', 'following_id')
->withPivot('is_following', 'is_blocked')
->wherePivot('is_following', true)
->wherePivot('is_blocked', false)
->paginate(3);
}
public function userPosts()
{
return $this->hasMany(Post::class, 'postable_id', 'id')
->where('postable_type', User::class);
}
ご覧のとおり、2 つのブール値を使用して、ユーザーがフォローしているかブロックされているかを判断しています。また、Post モデルはポリモーフィック モデルです。私が試したことはいくつかありますが、その中で、上記の hasMany Posts 関係を使用せずに hasManyThrough を試しました。各ユーザーの投稿を取得しましたが、上記のブール値を使用しているため、hasManyThrough でそれらを使用できませんでした。ユーザーがフォローしているかブロックされているかに関係なく、単に following_id に基づいて投稿を取得しました。
次に、別のサービス クラスで、以下のメソッドを試しました (コードを簡単に維持するために別のクラスを使用しています)。どちらも各ユーザーの投稿を取得しますが、2 人のユーザーからの 5 つの投稿に基づいて N+1 問題と 12 の重複クエリを追加します。また、いくつかの条件に基づいて結果をフィルタリングする必要があるため、クエリがさらに追加される可能性があります。さらに、画像、コメントなど、投稿ごとに他のアイテムを取得する Laravel リソース コレクションを使用しているため、クエリの量はさらに増加します。わかりません。おそらく私はやりすぎで、もっと簡単な方法があります。
また:
$following = $request->user()->usersImFollowing();
$posts = $following->map(function($user){
return $user->userPosts()->get();
})->flatten(1);
return $posts;
または
$postsfromfollowing = [];
$following = $request->user()->usersImFollowing()->each(function($user) use (&$postsfromfollowing){
array_push($postsfromfollowing,$user->userPosts);
});
$posts = Arr::flatten($postsfromfollowing);
return $posts;