35

I need to be able to get a Models Relationship including its soft deleted elements, but only for this 1 instance. I do not want to change the model so that every time I use the relationship it returns all the soft deleted records too.

How can I achieve this?

User Model

class User extends Authenticatable
{
  public function contacts(){
    return $this->hasMany('App\Contacts','user_id','id');
  }
}

Controller

$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(); //Something like this
return $user;

How can I get the trashed rows only this 1 time inside my controller?

Thanks

S_R
  • 1,818
  • 4
  • 27
  • 63

4 Answers4

78

You can use withTrashed method in different ways.

To associate the call with your relationship you can do as follows:

public function roles() {
    return $this->hasMany(Role::class)->withTrashed();
}

To use the same in the fly:

$user->roles()->withTrashed()->get();

For your special scenario:

$user->contacts()->withTrashed()->get();
Pusparaj
  • 1,469
  • 1
  • 12
  • 19
  • It completely wen't over my head to just run the `withTrashed()` method in the view itself where I am looping over it. Probably the cleanest way to achieve this, thanks! – S_R Aug 02 '18 at 13:31
  • How can I filter records when fetching records using withTrashed()? https://laracasts.com/discuss/channels/laravel/how-to-filter-records-when-using-softdelete-withtrashed – hassanrazadev Mar 27 '20 at 07:46
34

You can also eager load them by adding a clause to the with() method

$user = User
   ::with(['contacts' => fn($q) => $q->withTrashed()])
   ->findOrFail($id);
Alistair R
  • 776
  • 9
  • 16
3

Looking at the Laravel Documentation on Querying soft deleted models:

//The withTrashed method may also be used on a relationship query: 
$flight->history()->withTrashed()->get(); 

The problem is using $user->contacts returns collection of related records of contacts to user, while $user->contacts() will make a new query.

  • 1
    How would you go about nested relationships? A belongsToMany B and B hasMany C? I need a way to say "Give me ALL results for A (including trashed) where ALL relations (B and B->C) show trashed elements". Is this possible? – Julian Dec 04 '18 at 22:48
0

You can do this with:

$user = User::findOrFail($id);

$user->contacts()->withTrashed()->get(); //get all results

return $user;

When you call the relation with (), you can append the withTrashed() method. After that you need to get() the results.

Robin Dirksen
  • 3,322
  • 25
  • 40