People tend to forgot that soft delete is just QoL for accidental deletion. You should still always backup your original database in a schedule for data safety. Also archiving usually correlates to cheaper storage with more lifespan but less activity, something like in HDD instead of SSD or AWS Glacier instead of S3.
Having a 'deleted' table is good, but you'd also have to have the same setup for all the child/foreign-key tables. Doing a delete/restore would need a careful sequence of cloning lots of data in a specific order to/from all the tables. You could write a script to automate it but then this code has to be changed when the 'normal' DB schema or app changes. It sounds like a great idea but there are now more maintenance headaches any time you update things.
I like the idea of moving the deleted records to a separate table: users and users_deleted or whatever...it is gonna inflate the database though, but it is more pro approach in case we don't want to lose the deleted data, as some mentioned "accidental deletion" or legal reasons and so on.
It would be interesting seeing a project that implements the archive method, and that can accessed by the users and be restored or permanently deleted.
you're amazing! i'd love to see a project that implements the archive method, and that can accessed by the users and be restored or permanently deleted
The second problem on 2:40 is not only a soft-delete problem. It's the problem of Laravel constant use of magik behind - for this example the problem lays in global scopes. Soft delete is a global scope. When you for example want to have a global scope that will limit the results of a query only to the rows owned by the user, it will also wont work by using Laravel DB facade. Same goes with mutators in models - they will only work on the Model instance, using data from DB will be detached from this logic.
We could consider moving records instead of using soft or hard deletes. For instance, we can create a separate schema in PostgreSQL specifically for deleted records.
I always thought that soft delete only existed in case you have a damn big table where deleting a record takes a long time because the DB need to reorganize the indexes of the table, so you only flag that the record it's deleted, and then you create a job to delete it at 00h or something
I solve the unique constraint problem with a calculated non-null column based on deleted_at and use that with the intended unique column(s) as a compound unique index.
I would much rather deal with the soft delete issues rather than accidentally deleting through cascading. Maybe if my testing was perfect it wouldn't happen, but chasing the accidental cascades always feels like chasing ghosts. I will admit the unique slug issue is annoying on the soft delete side of things though!
5:00 that's a feature, not a bug. The last thing you want is for a User to close their account and then someone else create one with their old email address.... same thing with usernames, etc.
@@dansvel no, it should be caught and handled in a different way. Hey, you already have an account with us that has not yet been purged, you want to recover it? Yes/No and continue from that point.
My initial guess was using a deleded_[table]. but that would get messy quickly as you have to create a deleted table for every table? Softdeleable trait with a deleted_models table solves that problem. P.S nevery heard of this spatie package. nice! Archive sounds like a great feature. "It Depends" cap is awesome!
Hi, I am going back to Laravel since 2019 where I focused on JS and got totally stayed out of the loop for Laravel. Can you point me to learning resources so I can be updated to Laravel standard practices?
Not sure what exactly standard practices you wanna see and which projects you would work on: Web? API? SaaS? Etc. I guess all I can quickly send is my learning roadmap: laraveldaily.com/roadmap-learning-path
Inconveniences with programmatic deletion occur even when it is necessary to delete or restore records in a tree of the nested set type. Solvable, but inconvenient
I don't use AI-generated content on Laravel Daily. Or maybe I misunderstood your question, sorry. It may have positive effect on SEO in terms of keywords, but very bad effect on audience satisfaction.
All those problems mentioned in video aren't problems, but all the good thing of soft deletes and why I use them, among the case to keep data in my database as some kind of archive. Nuno is completely wrong on this one from my perspective. And one where condition wouldn't affect performance in any noticeable way. In real application most of the queries would have few where conditions anyway.
Maybe we need a way to completely delete "Soft deleted records" after certain time.. for example of we have soft deleted records older than 3 months, it should be deleted completely
That only applies to user sensitive data. Soft delete is the same method as archiving business records such as past tickets, etc. If you want to keep user activity for stats, you can permanently delete their personally identifiable data and soft delete their user activity.
in Brazil it's the opposite for some cannabis related data. You're mandated to keep the data for some decades. (I could be wrong... I've heard this from a dev on facebook but never looked for the source). I guess you can soft delete (don't quote me on that), but you need the data for compliance reasons (the cannabis business for medicinal purposes are quite strictly regulated here)
The unique email issue should be handled by changing the unique index on email_address to one on email_address and deleted_at - however NULL is a value which is never unique - in other words literally NULL != NULL. With hindsight it was stupid to use NULL as not deleted. I a non-NULL value like the base timestamp 1/1/1971 or similar should have been used to indicate not-deleted.
I'm personally not much of a fan of softdeletes. I see it working well on use cases like blogs but I barely found any nifty uses for it so far aside from the comment system I wrote from scratch. Outside of that I always found it a layer of complexity not worth having on my own projects.
People tend to forgot that soft delete is just QoL for accidental deletion. You should still always backup your original database in a schedule for data safety. Also archiving usually correlates to cheaper storage with more lifespan but less activity, something like in HDD instead of SSD or AWS Glacier instead of S3.
What is QoL?
@@henlyforbesly2176 quality of life
Having a 'deleted' table is good, but you'd also have to have the same setup for all the child/foreign-key tables. Doing a delete/restore would need a careful sequence of cloning lots of data in a specific order to/from all the tables. You could write a script to automate it but then this code has to be changed when the 'normal' DB schema or app changes. It sounds like a great idea but there are now more maintenance headaches any time you update things.
Povilas thank you - good points. I actually use prefixes for deleted users email, to allow those user register again.
Povilas,
Thanks for another great video. It would be great to see a new video showing these points in practice, in real life scenarios.
I treat soft delete as "archive" and force delete as "delete"
Even better to use "destroy" term, avoid ambiguity introduced by softdeletes
I'm just starting to use Laravel's Eloquent SD's so this video is an interesting coincidence, very informative!
I often added index to softdelete column in migration... It's a life saver in many situations
I like the idea of moving the deleted records to a separate table: users and users_deleted or whatever...it is gonna inflate the database though, but it is more pro approach in case we don't want to lose the deleted data, as some mentioned "accidental deletion" or legal reasons and so on.
It would be interesting seeing a project that implements the archive method, and that can accessed by the users and be restored or permanently deleted.
See Soft Deletes as the archive... Just use a Schedule Command to go over the soft deletes and delete all the data permanently.
@@JohnnyBigodes I was referring to a global archive like the one he showed from spatie.
Thanks! I learned a lot from this video.
you're amazing! i'd love to see a project that implements the archive method, and that can accessed by the users and be restored or permanently deleted
that "as much as possible" is the key in his tweet
I agree with Nuno. I regret using soft deletes in most of the models I used in the past.
I use soft delete as an archive. As for the performance issue, it can be solved by partitioning the table at the database level.
That thumbs up bubble on your screen at 8:37, just showed up because your camera saw a thumb on screen. I also always forget to disable such features.
Stupid functionality. I can't think of any reason these features are enabled by default... Apple is going Microsoft the Microsoft way.
I face problems when write Pest test to force delete user when User Model use SoftDelete trait.
The second problem on 2:40 is not only a soft-delete problem. It's the problem of Laravel constant use of magik behind - for this example the problem lays in global scopes. Soft delete is a global scope. When you for example want to have a global scope that will limit the results of a query only to the rows owned by the user, it will also wont work by using Laravel DB facade. Same goes with mutators in models - they will only work on the Model instance, using data from DB will be detached from this logic.
We could consider moving records instead of using soft or hard deletes. For instance, we can create a separate schema in PostgreSQL specifically for deleted records.
I always thought that soft delete only existed in case you have a damn big table where deleting a record takes a long time because the DB need to reorganize the indexes of the table, so you only flag that the record it's deleted, and then you create a job to delete it at 00h or something
I solve the unique constraint problem with a calculated non-null column based on deleted_at and use that with the intended unique column(s) as a compound unique index.
Could you specify that better? I would love to know more about it. Thank you
Maybe logging the deleted record also and a choice with hard delete by schedule, store it in directory with it's table name
Nice video, thanks!
I would much rather deal with the soft delete issues rather than accidentally deleting through cascading. Maybe if my testing was perfect it wouldn't happen, but chasing the accidental cascades always feels like chasing ghosts. I will admit the unique slug issue is annoying on the soft delete side of things though!
5:00 that's a feature, not a bug. The last thing you want is for a User to close their account and then someone else create one with their old email address.... same thing with usernames, etc.
so if you or someone create account with the same email, we'll treat it as recovery account.
@@dansvel no, it should be caught and handled in a different way. Hey, you already have an account with us that has not yet been purged, you want to recover it? Yes/No and continue from that point.
My initial guess was using a deleded_[table].
but that would get messy quickly as you have to create a deleted table for every table?
Softdeleable trait with a deleted_models table solves that problem.
P.S nevery heard of this spatie package. nice!
Archive sounds like a great feature.
"It Depends" cap is awesome!
Thanks for this
I'm curious, why is the query with deleted_at =null slower
Any extra condition to the query makes it slower. Just more work for database.
Hi, I am going back to Laravel since 2019 where I focused on JS and got totally stayed out of the loop for Laravel. Can you point me to learning resources so I can be updated to Laravel standard practices?
Not sure what exactly standard practices you wanna see and which projects you would work on: Web? API? SaaS? Etc.
I guess all I can quickly send is my learning roadmap: laraveldaily.com/roadmap-learning-path
Inconveniences with programmatic deletion occur even when it is necessary to delete or restore records in a tree of the nested set type. Solvable, but inconvenient
in addition global scopes for model cause a lot of problems
Please implement the project
i have a question does AI content in lardaily effect SEO ? WHAY you don't use AI ?
I don't use AI-generated content on Laravel Daily. Or maybe I misunderstood your question, sorry.
It may have positive effect on SEO in terms of keywords, but very bad effect on audience satisfaction.
@LaravelDaily oh i got it 👍 thanks
All those problems mentioned in video aren't problems, but all the good thing of soft deletes and why I use them, among the case to keep data in my database as some kind of archive. Nuno is completely wrong on this one from my perspective. And one where condition wouldn't affect performance in any noticeable way. In real application most of the queries would have few where conditions anyway.
TLDW "soft delete problems" are skill issues
to be honest cascade soft delete should be in the core. it doesn't make sense otherwise
I treat softdelete as active status of a record.
Maybe we need a way to completely delete "Soft deleted records" after certain time.. for example of we have soft deleted records older than 3 months, it should be deleted completely
You can easily write a scheduled task for it.
Laravel already has the purging concept, it gives you all the logic for managing exactly this, I use it all the time.
For legal reasons, it is indeed a common business logic, we can't simply soft delete records
That only applies to user sensitive data. Soft delete is the same method as archiving business records such as past tickets, etc. If you want to keep user activity for stats, you can permanently delete their personally identifiable data and soft delete their user activity.
in Brazil it's the opposite for some cannabis related data. You're mandated to keep the data for some decades. (I could be wrong... I've heard this from a dev on facebook but never looked for the source).
I guess you can soft delete (don't quote me on that), but you need the data for compliance reasons (the cannabis business for medicinal purposes are quite strictly regulated here)
The unique email issue should be handled by changing the unique index on email_address to one on email_address and deleted_at - however NULL is a value which is never unique - in other words literally NULL != NULL. With hindsight it was stupid to use NULL as not deleted. I a non-NULL value like the base timestamp 1/1/1971 or similar should have been used to indicate not-deleted.
Newer use soft deletes.
I'm personally not much of a fan of softdeletes. I see it working well on use cases like blogs but I barely found any nifty uses for it so far aside from the comment system I wrote from scratch. Outside of that I always found it a layer of complexity not worth having on my own projects.
Do you have discord? Btw. I following your Laravel Roadmap.
We have a Discord for premium Laravel Daily members, you get invitation after purchasing the membership.
How