When writing a query it's common to use closures when using advanced clauses or grouping conditions together in-order for the query to behave as expected.
$users = DB::table('users')
->where('name', '=', 'John')
->where(function ($query) {
$query->where('votes', '>', 100)
->orWhere('title', '=', 'Admin');
})
->get();
With more complex queries which have numerous closures the repeated use of the $query
argument can make readability awkward.
$users = DB::table('users')
->where('name', '=', 'John')
->where(function ($query) {
$query->whereHas('role', function ($query) {
$query->whereIn('slug', ['leader', 'deputy'])
->whereHas('team', function ($query) {
$query->whereIn(
'slug',
['sales', 'finance'],
);
});
});
})
->get();
By replacing the $query
arguments with a variable named as per the table's name, eg $teams
, the methods then appear prefixed with the table they're operating on which can make things feel more fluent.
$users = DB::table('users')
->where('name', '=', 'John')
->where(function ($users) {
$users->whereHas('role', function ($roles) {
$roles->whereIn('slug', ['leader', 'deputy'])
->whereHas('team', function ($teams) {
$teams->whereIn(
'slug',
['sales', 'finance'],
);
});
});
})
->get();
This approach also helps when scanning over many lines or reading things out of context, for example when trying to debug a certain query's conditions.
// Need to add the "senior-managers"
// to the condition for the teams table
// Could this be the right condition,
// which table's slug is this?
$query->whereIn(
'slug',
['sales', 'finance'],
);
// If the query argument has been named,
// then we immediately know which table it is 🙂
$teams->whereIn(
'slug',
['sales', 'finance'],
);
Top comments (0)