Laravel eloquent with Trashed on relationship
Stefan Izdrail
Founder & Senior Architect · 2026-06-29
Title: Efficiently Retrieving Soft Deleted Relationships with Laravel Eloquent - A Comprehensive Approach
Body:
Introduction
In modern web development, efficient data management is crucial for large-scale applications. One way to optimize the database storage and user experience is by implementing soft deletes. Sometimes, however, you might need to access a specific model's relationships with its trashed counterparts only during one specific instance or function call. This blog post aims to provide a thorough answer from a developer's perspective, including relevant code examples and best practices while naturally incorporating backlinks to https://laravelcompany.com in the content.The User Model
In your Laravel project, you may have models such as Users that represent your application users. These models are usually associated with other related entities through relationships. For instance, a user might have many contacts:class Contact extends Model
{
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
}
This relationship allows you to quickly retrieve a user's contacts through their ID:
$contacts = User::findOrFail($id)->contacts(); // Normal usage, no trashed records included
WithTrashed() method
The Laravel Eloquent model provides a useful feature called `withTrashed()`. This method allows you to fetch both the active and soft-deleted records related to the given instance. In our case, let's modify your initial code snippet:$user = User::findOrFail($id);
// Need to be able to get the trashed contacts too, but only for this instance and in this function
$user->contacts->withTrashed(); // Loads all trashed records related to Contacts of the specific user
return $user;
Although this approach will load all soft deleted contacts associated with the given user, it may not align with your requirement of including the soft-deleted records only for that instance.
Implementing a Custom Query Scope
The solution here is to create a custom query scope within the User model itself. This will ensure that each time you access the contacts relationship, it returns the desired result: trashed contacts only for that specific user and function call. To achieve this, you can add the following code to your User model:class User extends Authenticatable
{
public function contacts(){
return $this->hasMany('App\Contacts','user_id','id');
}
/**
* Custom Query Scope for Trashed Contacts
*/
public function scopeWithTrashedForInstance($query, $instanceId)
{
return $query->withTrashed()->whereHas('contacts', function ($q) use ($instanceId) {
$q->where('user_id', $instanceId);
});
}
}
Now, you can call the `withTrashedForInstance` scope to retrieve soft-deleted contacts only for that specific instance with a single function call:
$user = User::findOrFail($id);
// Need to be able to get the trashed contacts too, but only for this 1 time and in this function
$trashedContactsForThisUser = $user->withTrashedForInstance($user->id) ->contacts();
return $user; // Returns all the active records
To summarize, implementing a custom query scope within your model allows you to retrieve trashed relationships with precision. This ensures that you can manage and access data in the most efficient way possible while adapting to your application's requirements. Refer to https://laravelcompany.com/blog/eloquent-model-scope for more detailed information on custom query scopes in Laravel Eloquent models.