How do I set soft delete on an intermediate table which is connecting two different types of entities? I've added deleted_at column, but the docs say that I need to put this into the model:
protected $softDelete = true;
Of course, I don't have a model for an intermediate table. Any idea?
Soft delete is a security feature to help protect backup data even after deletion. With soft delete, even if a malicious actor deletes the backup of a database (or backup data is accidentally deleted), the backup data is retained for 14 additional days. This allows the recovery of that backup item with no data loss.
Normally when you run a DELETE statement in a database, the data's gone. With the soft delete design pattern, you add a bit column like IsDeleted, IsActive, or IsArchived to the table, and instead of deleting rows, you flip the bit column. This can buy you a few advantages: Easier/faster undeletes.
Hard deletes are hard to recover from if something goes wrong (application bug, bad migration, manual query, etc.). This usually involves restoring from a backup and it is hard to target only the data affected by the bad delete. Soft deletes are easier to recover from once you determine what happened.
One common use case that is a first step outside that pattern comes when the application needs to perform a soft delete, making records appear to be deleted while retaining the actual database record. This can be handled simply by adding a flag column and checking it each time you query the database.
You can put a constraint on the Eager Load:
public function groups()
{
return $this
->belongsToMany('Group')
->whereNull('group_user.deleted_at') // Table `group_user` has column `deleted_at`
->withTimestamps(); // Table `group_user` has columns: `created_at`, `updated_at`
}
Instead of HARD deleting the relationship using:
User::find(1)->groups()->detach();
You should use something like this to SOFT delete instead:
DB::table('group_user')
->where('user_id', $user_id)
->where('group_id', $group_id)
->update(array('deleted_at' => DB::raw('NOW()')));
You could also use Laravel's Eloquent BelongsToMany
method updateExistingPivot
.
$model->relation->updateExistingPivot($relatedId, ['deleted_at' => Carbon\Carbon::now()]);
So to use @RonaldHulshof examples you have a User model with a groups relationship which is a belongsToMany
relationship.
public function groups() {
return $this->belongsToMany(Group::class)->whereNull('groups_users.deleted_at')->withTimestamps();
}
Then in order to soft delete the pivot table entry you would do the following.
$user->groups()->updateExistingPivot($groupId, ['deleted_at' => Carbon\Carbon::now()]);
As far as I understand it; an intermediate table is simply a length of string attaching one tables record to a record in another table and as such it does not require a soft delete method.
To explain, imagine you have a Users table and a Groups table, each user can have more than one Group and each Group can belong to more than one User. Your pivot table may be User_Group
or something like that and it simply contains two columns user_id
and group_id
.
Your User
table and Group
table should have a deleted_at
column for soft deletes, so when you "delete" say a Group, that group association will not appear in $User->Groups()
while the pivot table row has remained unaffected. If you then restore that deleted Group, it will once again appear in $User->Groups()
.
The pivot table row should only be affected if that group record is hard deleted, in which case the pivot rows should also be hard deleted.
Now I have explained why I do not believe you need to add soft delete to a pivot table; is there still a reason why you need this behavior?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With