Laravel のEloquent モデルについて


Eloquentに関して初歩的な質問をさせてください。  
get()で BelongTo 先のテーブルのデータを取得することができませんでした。

[code]

    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\Relations\BelongsTo;
    
    class Item extends Model
    {
        public function user(): BelongsTo
        {
            return $this->belongsTo('App\User');
        }
    }
    
[/code]

[code]

     $item = Item::where('id', 1)->get();
    
[/code]

としたところ関連付けしてあるユーザの情報を取ることができませんでした。

[code]

     $item = Item::where('id', 1)->first();
    
[/code]

とすることで、ユーザテーブルがJoinされ、ユーザ情報の取得ができました。

getでは、Modelに該当しているテーブルのみからしかデータを取得できないのでしょうか？




Eloquentにjoinという概念は無いです。

belongTo()のようなリレーションシップを作った場合の挙動は、通常Lazy
Loadingとなり、今回の例では以下のようにしてusersテーブルのデータを取得します。

[code]

    $item = Item::where('id', 1)->get();
    echo $item[0]->user->name;
    
    //itemに紐付いたuserの名前を表示
    
[/code]

この際、Eloquentでは以下のようなSQLを実行します。

[code]

    select * from items where id = 1;
    select * from users where id = {items.user_id};
    
[/code]

またテックブログや解説書で推奨されるwithを使った方法(Eager Loading)では以下となります。

[code]

    $item = Item::with('users')->where('id', 1)->get();
    echo $item[0]->user->name;
    
    //itemに紐付いたuserの名前を表示
    
[/code]

この際、Eloquentでは以下のようなSQLを実行します。

[code]

    select * from items where id = 1;
    select * from users where id in ({items.user_id});
    
[/code]

そして今回勘違いされているfirstを使った場合は以下となります。

[code]

    $item = Item::where('id', 1)->first();
    echo $item->user->name;
    
    //itemに紐付いたuserの名前を表示
    
[/code]

[code]

    select * from items where id = 1 limit 1;
    select * from users where id = {items.user_id};
    
[/code]

違いは、get()は複数件返ることを前提に、各userのコレクションを配列に格納して返すのに対して、first()は、1件しか返らない前提なので、コレクションそのものが返ってきます。おそらくあなたは、get()のときも、$item->user->name
として値が取り出せると期待していたのでしょうが、そうならず、fist(）では、$item->user->name
で取り出せたので、joinされた！と勘違いしているのではないでしょうか。

