こんにちは!とびろぐ管理人のとびうおです。
今回はLaravelにて2つのコレクションを足し合わせたい時にどうやるのかについて解説していきたいと思います。
ダメな例
まず、コレクションにただ足すだけではadd()メソッドを使えばいいのですが、それでは以下のようなコードは動きません。
//ステータスがpre_activeとactiveのuserを取得したい。
$active_users = User::where('status','active')->get();
$pre_active_suers = User::where('status','pre_active')->get();
$active_users->add($pre_active_users);
collectionの中に足していくaddメソッドでは、
collectionの中に足されてしまうので、
ただ足すということができない。
また、これも動きません。
また、これもうまくいきません。
//ステータスがpre_activeとactiveのuserを取得したい。
$active_users = User::where('status','active')->get();
$pre_active_suers = User::where('status','pre_active')->get();
$users = $active_users + $pre_active_users;
これができればかなり楽ですがね….
クエリの書き方を工夫する!
この場合におけるベストプラクティスはクエリの書き方を工夫するです。
例えば、
//ステータスがpre_activeとactiveのuserを取得したい。
$active_users = User::where('status','active')->orWhere('status','pre_active')->get();
と言う形でクエリを工夫することで解決ができます。
おそらく、やりたいことはクエリを工夫すればできるはずです。
“かつ”条件では簡単にかけますが、
“または"の条件をクエリで書くのは少し苦手感がありますよね
例えば、userのstatusがactive または userと紐づいているpostのuser_idがある人(記事を投稿したことがある人)を返したいと思った時には、実はこんな書き方ができます。
$user = User::where('status',"active")->orWhere->whereHas('posts', function ($query) {
return $query;
})->get();
この時
orWhere
というのを使ってます!
このように書くことができます。
どうしてもcollectionを足したい時
どうしてもコレクションを足したい!と言う時があると思います。
その場合はforeachとaddを使っていきましょう。
//ステータスがpre_activeとactiveのuserを取得したい。
$active_users = User::where('status','active')->get();
$pre_active_suers = User::where('status','pre_active')->get();
foreach($pre_active_suers as $users){
$active_users->add($users)
}
このようにすると、$active_usersに$pre_active_suersが入った状態で出力されるようになります。
ただ、この場合、先ほどの「userのstatusがactive または userと紐づいているpostのuser_idがある人(記事を投稿したことがある人)を返したい」と言う時に以下のような書き方をしたとしましょう。
$users = User::where('status',"active")->get();
$post_users = User::whereHas('posts', function ($query) {
return $query;
})->get();
foreach($post_users as $user){
$post_users->add($users)
}
この時、statusがactiveでかつpostも持っているユーザーが$usersが被って2人出力されるというバグの原因になりうる挙動をしてしまいます。
逆に、先ほどのクエリを工夫するの方だと、
被りがでないで出力されます。
なのでコレクションで頑張ろう!ということをする際は
気をつけたほうがいいかもしれないですね
Laravelの他の記事
当ブログではこれ以外にもLaravelの記事を多く書いております!
気になる方は↓をチェック!
コメント