You check lang = en whereas in your structure above lang contains english and code contains en.
$pages = Page::with(['pagedetails.langs' => function($query){
$query->where('code', '=', 'en');
}])->get();
Should work
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Constraining in Nested Eager Loading
I'm having a hard time trying to use a Contrain in Nested Eager Loading. The idea of what I have: Pages wich can be in different languages. For this I have 4 tables: "langs", "pages", "pagedetails" and "pagedetail_lang". Something like:
langs
id, language, lang
1, english, en
2, french, fr
pages
id, description
1, home page
2, about page
3, contacts page
pagedetails
id, page_id, slug, title
1, 1, home-en, Home in English
2, 1, home-fr, Home in French
3, 2, about, About in English
4, 3, contacts, Contacts page in English and French
pagedetail_lang
id, pagedetails_id, lang_id
1, 1, 1
2, 1, 2
3, 3, 1
4, 4, 1
4, 4, 2
And I have these Models:
class Page extends Model
{
public function pagedetails()
{
return $this->hasMany('App\Pagedetail');
}
}
class Pagedetail extends Model
{
public function langs()
{
return $this->belongsToMany('App\Lang', 'pagedetail_lang');
}
}
I want to get the pages, with their pagedetails in English only, so I tried the following code.
$pages = Page::with(['pagedetails' => function($query){
$query->with(['langs' => function($query){
$query->where('lang', 'en');
}]);
}])->get();
But no matter what I do, the where clause doesn't work. I get the pagedetails in all languages. I have even tried using limit, but I still receive more than one result:
$query->where('lang', 'en')->limit(1);
Please or to participate in this conversation.