Laravel, Datatables, column with relations count
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Mastering Relationships in Laravel Datatables: Adding Relation Counts with Eloquent
As a senior developer working with Laravel, we constantly face the challenge of presenting complex relational data in a flat, consumable format. When using powerful tools like the Laravel Datatables package to display lists, adding derived information—such as counts, sums, or averages—is crucial for making the data actionable.
This post addresses a very common scenario: how to efficiently calculate and display the total number of related records (e.g., how many Training records a User has) directly within your Datatables output. We will explore the most idiomatic and performant ways to achieve this using Eloquent, ensuring your data presentation is both accurate and highly optimized.
The Challenge: Counting Many-to-Many Relationships
You have two models, User and Training, linked by a many-to-many relationship. Your initial query successfully fetches user details but lacks the aggregate count you need for each row.
The starting point provided is excellent for selecting basic user data:
public function getData()
{
$users = User::select(array('users.id', 'users.full_name', 'users.email', 'users.business_unit', 'users.position_id'))
->where('users.is_active', '=', 1);
return \Datatables::of($users)
->remove_column('id')
->make();
}
The goal is to augment this result set by adding a column showing the count of associated Training records for every user.
Solution 1: The Eloquent Way – Using withCount() (Recommended)
For simple counting operations where you want to fetch the main model data alongside a pre-calculated aggregate, the most elegant and readable solution in Laravel is using the withCount() method. This method performs the necessary SQL joins internally and hydrates the result set perfectly for Eloquent.
By adding withCount('trainings') to your query, Eloquent automatically calculates the count of related models and attaches it as an attribute (e.g., trainings_count) to each user object.
Here is how you modify your controller method:
use App\Models\User;
use Datatables;
public function getData()
{
$users = User::select(array('users.id', 'users.full_name', 'users.email', 'users.business_unit', 'users.position_id'))
->withCount('trainings') // <-- The magic happens here!
->where('users.is_active', '=', 1);
return Datatables::of($users)
->remove_column('id')
// You can now access the count directly via the relationship accessor
->addColumn('training_count', function ($user) {
return $user->trainings_count; // Accessing the count calculated by withCount()
})
->make();
}
Why this is best: This approach leverages Eloquent's built-in relationship handling. It keeps your data layer clean, adheres to the principles of Laravel development, and results in highly readable code. When building complex features, relying on Eloquent relationships rather than raw SQL joins minimizes the chance of introducing subtle bugs related to foreign key management.
Solution 2: The Raw SQL Way – Using leftJoin (For Maximum Control)
If you require highly specific control over the join type or need to perform more complex aggregations (like summing values across multiple joined tables simultaneously), a direct leftJoin combined with groupBy and COUNT() might offer greater performance control, especially in extremely large datasets.
public function getDataRaw()
{
$users = User::select(
'users.*',
DB::raw('COUNT(trainings.id) as training_count')
)
->leftJoin('trainings', 'users.id', '=', 'trainings.user_id')
->where('users.is_active', '=', 1)
->groupBy('users.id'); // Must group by all selected non-aggregated columns
return Datatables::of($users)
->remove_column('id')
->make();
}
While powerful, the withCount() method (Solution 1) is generally preferred for simple one-to-many counts because it integrates seamlessly with Eloquent's object-oriented approach. Always favor Eloquent methods when possible, as they provide a stronger abstraction layer over the underlying database operations, which is fundamental to building robust applications on the Laravel framework.
Conclusion
To successfully add relation counts to your Datatables output, choose between simplicity and elegance. For most use cases involving counting related models, utilize Eloquent's withCount('relation_name'). It provides a clean, maintainable solution that aligns perfectly with the power of the Laravel ecosystem. If you require highly customized SQL operations for complex reporting, then falling back to explicit leftJoin statements is an acceptable alternative. By mastering these techniques, you ensure your data presentation layer remains efficient and developer-friendly.