-1

I have chapter table. Each chapter may have multiple notes and each not is created by a user.

Table structure

users => id | name

chapters => id | title

notes => id | chapter_id | user_id

Relationship

//Chapter Model
public function notes()
{
    return $this->hasMany(Note::class, 'chapter_id', 'id');
}


//Note Model
public function user()
{
    return $this->belongsTo(User::class, 'user_id', 'id');
}

Now I'm trying to get all chapters and their notes and user who created the note.

Chapter::with([
    'notes' => function($q) {
        $q->select('id','chapter_id','note','noted_at');
    },
    'notes.user' => function($q) {
        $q->select('id','first_name','last_name');
    },
]);

I am getting the notes relation but user relation is null in each note

I also tried following but no luck

Chapter::with([
    'notes' => function($q) {
            $q->select('id','chapter_id','note','noted_at');
            $q->with('user:id,first_name,last_name');
        },
]);

My output should resembles to following json

{
   "id":2,
   "title":"Sed.",
   "notes":[
      {
         "id":82,
         "chapter_id":2,
         "note":"Dicta ipsam illum possimus qui non. Nihil sed ipsum et rem reprehenderit omnis aspernatur. Ut velit quo incidunt quaerat reiciendis.",
         "noted_at":383,
         "user":{
            "id":1,
            "first_name":"Fahad",
            "last_name":"Shaikh"
         }
      }
   ]
}

In simple words how can I eager load nested relationship user while constraining both notes and user relationship?

Fahad Shaikh
  • 307
  • 4
  • 16

1 Answers1

0

Try just this code below and you will get the notes with the user inside of each note

Chapter::with('notes.user')->get();

With the select part:

Chapter::with('notes', function($noteQueryBuilder) {
    $noteQueryBuilder->select('id','chapter_id','note','noted_at', 'user_id')
        ->with('user', function($userQueryBuilder) {
            $userQueryBuilder->select('id','first_name','last_name');
        });
})->get();

You need to include user_id if you want to limit the select on the notes cause its gonna be used to eager load the user for the notes. You can chain other conditions on the query builder of each entity.

N69S
  • 16,110
  • 3
  • 22
  • 36
  • Yes but my objective is to constrain `notes` and `user` relationship while eager loading both of them – Fahad Shaikh Mar 02 '21 at 17:41
  • @FahadShaikh They will both be eager loaded, what is the issue here ? what do you mean by "constrain" ? – N69S Mar 02 '21 at 17:45
  • "constrain" mean putting condition or adding statement on these relationships. https://laravel.com/docs/8.x/eloquent-relationships#constraining-eager-loads – Fahad Shaikh Mar 02 '21 at 17:50
  • @FahadShaikh Add the condition the condition in question to your original post. if you're talking about the `select` part, then you better use these methods https://stackoverflow.com/questions/24758603/dynamically-hide-certain-columns-when-returning-an-eloquent-object-as-json – N69S Mar 02 '21 at 17:52