Laravel query builder get custom attribute
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Mastering Custom Attributes in Laravel Queries: Getting Computed Values from Eloquent
As a senior developer working with Laravel and Eloquent, you often run into scenarios where your application logic calculates values that aren't stored directly in the database—these are custom attributes defined via accessors or mutators. When building complex queries, retrieving these computed values alongside standard column data can become a point of confusion.
The core challenge, as highlighted in your example, is how to instruct the Eloquent Query Builder to pull data from methods that calculate values rather than simple database columns. Trying to use with() for direct scalar access often fails because eager loading is designed primarily for retrieving related models, not arbitrary computed field values.
This post will explore the robust and efficient ways to retrieve custom attributes, including computed properties and flattened relationship data, directly within your Eloquent queries, all while avoiding raw SQL.
The Limitation of Standard Eager Loading
When you use methods like with('role'), Eloquent performs a separate query to fetch the related Role model. If you want only a specific field from that relationship (like the role's name), simply accessing it via dot notation in your main select statement often doesn't work directly because the structure returned is a nested model object, not a flattened scalar value.
Your approach of trying with('role:name') failed because while Laravel supports dot notation for eager loading, it primarily focuses on loading relationships or nested attributes defined in the model, not automatically flattening arbitrary accessor results into the main result set.
Solution 1: Selecting Custom Attributes Directly with select()
The most straightforward way to retrieve a computed attribute (like your getViewUrlAttribute) is to use the standard select() method combined with Eloquent’s ability to handle expression-based selections. Since these attributes are methods on the model, you can call them within the query builder.
If you need to select a calculated value, you must explicitly ask for it:
// In UserController.php
$users = User::select([
'id',
'name',
'email',
'created_at',
// Select the computed attribute directly
'view_url'
])->with('role:name') // Still eager load the relationship if needed
->limit($length);
return $users->get();
This approach forces Eloquent to calculate the result of getViewUrlAttribute() for every row in the result set, effectively injecting that calculated value into your final array. This is cleaner than trying to force it through the eager loading mechanism. For more complex mathematical operations or database functions, you can use selectRaw(), which provides maximum flexibility when dealing with raw SQL expressions safely:
// Example using selectRaw for complex calculations
$users = User::select(
'id',
'name',
DB::raw('CONCAT(email, "_view") AS view_url') // Example of a calculated field
)->get();
Solution 2: Flattening Relationship Data (Getting the Role Name)
To achieve your goal of getting just the role name ("role": "User") instead of the entire related object, we focus on ensuring that the relationship loading yields only the scalar data you need.
While complex nested attribute flattening often requires manual restructuring or using dedicated package features, for simple one-to-one relationships where you only need a single field from the related model, the with() method remains powerful. The key is to ensure your accessors and relationships are set up correctly on the parent model (User).
If you want to explicitly control what data is loaded during eager loading, stick to the standard relationship definitions in your User model (as shown in your example) and rely on the primary select() method for computed fields. If performance becomes an issue with deeply nested attributes, explore custom collection transformations after fetching the data, ensuring you adhere to best practices documented by Laravel.
Conclusion
Retrieving custom attributes from Eloquent queries is less about forcing them through eager loading and more about understanding how the Query Builder interacts with model methods. For computed fields like view_url, use explicit select() calls. For flattening relationship data, rely on well-defined Eloquent relationships and be prepared to handle the resulting nested structure or use targeted selectRaw expressions for maximum control over your data retrieval process. Mastering these techniques allows you to build highly optimized and expressive database interactions in Laravel.