Restoring Soft Deleted Models
Now, when you call the delete
method on the model, the deleted_at
column will be set to the current date and time. However, the model's database record will be left in the table. When querying a model that uses soft deletes, the soft deleted models will automatically be excluded from all query results.
To determine if a given model instance has been soft deleted, you may use the trashed
method:
if ($flight->trashed()) {
//
}
Restoring Soft Deleted Models
Sometimes you may wish to "un-delete" a soft deleted model. To restore a soft deleted model, you may call the restore
method on a model instance. The restore
method will set the model's deleted_at
column to null
:
$flight->restore();
You may also use the restore
method in a query to restore multiple models. Again, like other "mass" operations, this will not dispatch any model events for the models that are restored:
Flight::withTrashed()
->where('airline_id', 1)
->restore();
The restore
method may also be used when building relationship queries:
$flight->history()->restore();
Permanently Deleting Models
Sometimes you may need to truly remove a model from your database. You may use the forceDelete
method to permanently remove a soft deleted model from the database table:
$flight->forceDelete();
You may also use the forceDelete
method when building Eloquent relationship queries:
$flight->history()->forceDelete();
Querying Soft Deleted Models
Including Soft Deleted Models
As noted above, soft deleted models will automatically be excluded from query results. However, you may force soft deleted models to be included in a query's results by calling the withTrashed
method on the query:
use App\Models\Flight;
$flights = Flight::withTrashed()
->where('account_id', 1)
->get();
The withTrashed
method may also be called when building a relationship query:
$flight->history()->withTrashed()->get();
Retrieving Only Soft Deleted Models
The onlyTrashed
method will retrieve only soft deleted models:
$flights = Flight::onlyTrashed()
->where('airline_id', 1)
->get();
Replicating Models
You may create an unsaved copy of an existing model instance using the replicate
method. This method is particularly useful when you have model instances that share many of the same attributes:
use App\Models\Address;
$shipping = Address::create([
'type' => 'shipping',
'line_1' => '123 Example Street',
'city' => 'Victorville',
'state' => 'CA',
'postcode' => '90001',
]);
$billing = $shipping->replicate()->fill([
'type' => 'billing'
]);
$billing->save();
Query Scopes
Global Scopes
Global scopes allow you to add constraints to all queries for a given model. Laravel's own soft delete functionality utilizes global scopes to only retrieve "non-deleted" models from the database. Writing your own global scopes can provide a convenient, easy way to make sure every query for a given model receives certain constraints.
Writing Global Scopes
Writing a global scope is simple. First, define a class that implements the Illuminate\Database\Eloquent\Scope
interface. Laravel does not have a conventional location that you should place scope classes, so you are free to place this class in any directory that you wish.
The Scope
interface requires you to implement one method: apply
. The apply
method may add where
constraints or other types of clauses to the query as needed:
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class AncientScope implements Scope
{
/**
* Apply the scope to a given Eloquent query builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
$builder->where('created_at', '<', now()->subYears(2000));
}
}