Search code examples
laraveleloquentlaravel-livewire

Laravel/Livewire: Use withTrashed() on model route binding on to show deleted records


In the list I display the latest topic, including those that is deleted.

function latest()
{
    return Topic::withTrashed()->latest();
}

For displaying a single topic I have a Livewire component with that topic passed into it.

class ShowTopic extends Component
{
    public $topic;

    public function mount(Topic $topic)
    {
        $this->topic = $topic;
    }

    public function render()
    {
        return view('livewire.show-topic', [
            'topic' => $this->topic,
        ]);
    }
}

But when I go to a single topic that is deleted, it doesn't show. How can I use withTrashed() on model route bindings to show deleted records with my Livewire component?


Solution

  • You can overwrite the resolveRouteBinding() method on your Eloquent model, and conditionally remove the SoftDeletingScope global scope.

    Here I'm using a policy for that model to check if I can delete the model - and if the user can delete it, they can also see it. You could implement any logic you want, or remove the global scope for all requests if that is more suitable for your application.

    use Illuminate\Database\Eloquent\SoftDeletingScope;
    
    class Topic extends Model {
        // ...
    
        /**
        * Retrieve the model for a bound value.
        *
        * @param  mixed  $value
        * @param  string|null  $field
        * @return \Illuminate\Database\Eloquent\Model|null
        */
        public function resolveRouteBinding($value, $field = null)
        {
            // If no field was given, use the primary key
            if ($field === null) {
                $field = $this->getKey();
            }
    
            // Apply where clause
            $query = $this->where($field, $value);
    
            // Conditionally remove the softdelete scope to allow seeing soft-deleted records
            if (Auth::check() && Auth::user()->can('delete', $this)) {
                $query->withoutGlobalScope(SoftDeletingScope::class);
            }
    
            // Find the first record, or abort
            return $query->firstOrFail();
        }
    }