リレーション先にデータがあるものだけを取得したいなーと思って色々困ったのでメモです。
前提
users テーブルと lessons テーブルがあります。
user は lessonを何個でも自由に作成できるので、1対多の関係です。
lessonsテーブルの user_id カラムにて、どのuserが作った lessonかを紐づけています。
usersテーブル

lessonsテーブル

ダメだった書き方
$users = User::join('lessons', 'lessons.user_id' , '=' ,'users.id')->get();
こう書くと、一見ちゃんとlessonsテーブルにデータがあるユーザーだけが取得できたように見えたのですが、、
本当は $user->id が 1 の人は山田さんのはずなのに、違う名前or空欄になるというおかしなことになっていました。
うまくいった書き方
$users = User::select('users.id as id' ,'users.name', 'users.email', 'lessons.title' , 'lessons.user_id as user_id') ->join('lessons', 'lessons.user_id' , '=' ,'users.id')->get();
select(”) の中に色々書いてるのですが、 as を使っている部分がポイントです。
users.id as id とすることで、ちゃんと user id が1の人は山田さんになりました。 でもこの書き方だと取得したい内要をselectに全部書かないと・・・?他にいい書き方があるのかなー。気になります。
また、今回の場合だと1人で何個もlessonを作れるので同じ人が何個も取得できてしまうので、重複分を削除しました。
$users = $users->unique('user_id'); $users->values()->all();
user_id をキーに重複を削除しています。
これでうまく行きました!