You can customize joins by passing a callback as the second argument to joinRelationship().
Basic Conditions
Use the $join instance to apply standard join conditions like where() or to change the join type:
User::joinRelationship('posts', fn ($join) => $join->where('posts.approved', true));
// Change join type inside callback
User::joinRelationship('posts', fn ($join) => $join->left());
Nested Callbacks
For nested relationships, pass an array where keys are the relationship names and values are the callbacks:
User::joinRelationship('posts.comments', [
'posts' => fn ($join) => $join->where('posts.published', true),
'comments' => fn ($join) => $join->where('comments.approved', true),
]);
Belongs To Many
For belongsToMany relationships, pass an array containing the relationship key and a nested array for the tables involved (the relationship table and the pivot table):
User::joinRelationship('groups', [
'groups' => [
'groups' => function ($join) {
// ...
},
'group_members' => fn ($join) => $join->where('group_members.active', true),
]
]);
User::joinRelationship('posts', fn ($join) => $join->where('posts.approved', true));
User::joinRelationship('posts.comments', [
'posts' => fn ($join) => $join->where('posts.published', true),
'comments' => fn ($join) => $join->where('comments.approved', true),
]);