Automatically deleting related rows in Laravel (Eloquent ORM)
I believe this is a perfect use-case for Eloquent events (http://laravel.com/docs/eloquent#model-events). You can use the "deleting" event to do the cleanup:
class User extends Eloquent
{
public function photos()
{
return $this->has_many('Photo');
}
// this is a recommended way to declare event handlers
public static function boot() {
parent::boot();
static::deleting(function($user) { // before delete() method call this
$user->photos()->delete();
// do the rest of the cleanup...
});
}
}
You should probably also put the whole thing inside a transaction, to ensure the referential integrity..
Delete Rows Older than 30 Days Using Laravel Eloquent ORM
- You have a typo. Try
MyTable::whereDate( 'created_at', '<=', now()->subDays(30))->delete();
- It would run gracefully
Delete all relation when Deleting a row in laravel
Laravel does not instantiate the related models that it deletes, which is why notifications are deleted when you directly delete a comment, but not when comments are deleted by deleting a post. You would have to instantiate the comments when deleting a post to make it work.
class Post extends Model {
public function notifications() {
return $this->morphOne(Notification::class, 'to');
}
public function comments() {
return $this->hasMany(Comment::class, 'post_id');
}
public static function boot() {
parent::boot();
static::deleting(function($post) {
// here you could instantiate each related Comment
// in this way the boot function in the Comment model will be called
$post->comments->each(function($comment) {
// and then the static::deleting method when you delete each one
$comment->delete();
});
$post->notifications()->delete();
});
}
}
Just for the records, I add what we discuss in the comments since it can serve others who encounter the same issue, and in the comments it can go unnoticed. Credit is for OP @Mahmoud Ben Jabir.
But if the post has 100 comments It will execute 100 query to delete them ! I will Figure out how to delete with minimum queries...
I already have onDelete on comments, but the notifications are polymorphic so it won't work on them...
The solution I will use is:
1- Get Ids of Comments that are related to the Post.
2- Delete from Notifications where type IS Comment AND id in (ids).
3- Delete Comments related to the Post.
4- Delete The Notifications Related to the Post
5- Delete The Post.
public static function boot() {
parent::boot();
static::deleting(function($post) {
// 1- Get Ids of Comments that are related to the Post.
$ids = $post->comments()->pluck('id');
// 2- Delete from Notifications where type IS Comment AND id in (ids).
Notification::where('entity_type', 'App\Comment')->whereIn('entity_id', $ids)->delete();
// 3- Delete Comments related to the Post.
$post->comments()->delete();
// 4- Delete The Notifications Related to the Post
$post->notifications()->delete();
});
// 5- Delete The Post.
}
Laravel - Delete with all relations
If you are using MySQL (or any RDBMS which supports cascading) you can cascade deleting on database level. If don't, you have to handle it manually on controller or by model event listening functions.
See documentation on migrations detailing foreign key constrains.
Schema::create('order_items', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('order_id');
$table->timestamps();
$table->foreign('sell_order_id')
->references('id')
->on('orders')
->onDelete('cascade');
});
Note: Laravel supports soft deletes out of the box, as well as cascading soft deletes, see following article https://laravel-news.com/cascading-soft-deletes-eloquent
How to delete single (many-) rows from one-to-many relations in Laravel 5.5
If you want to delete related items of your model but not model itself you can do like this:
$channel->labels()->delete();
It will delete all labels related to the channel.
If you want to delete just some of labels you can use where()
$channel->labels()->where('id',1)->delete();
Also if your relation is many to many it will delete from third table too.
Deleting eloquent relationship laravel
you can do something like below in destroy method:
public function destroy($id)
{
//you have $order id, find the order and then the relation with orderItems
$order = Order::find($id);
foreach($order->orderItem as $orderItem){
$orderItem->goldSilver()->delete();
}
$dltorder = $order->orderItem()->delete();
if($dltorder){
return response()->json([
'status'=>'Success',
'message'=>'Order deleted'
],200);
}
}
Deleting a relational item if it's not in the request in Laravel
I believe you want to remove the quote items that are not in the request.
So you might want to do something like this:
foreach (request('quoteItems') as $quoteItem => $item) {
$assignedItem = QuoteItems::where('id',$quoteItem)->first();
$assignedItem->id = $item['id'];
$assignedItem->price = $item['price'];
$assignedItem->cost = $item['cost'];
$assignedItem->save();
}
QuoteItems::where('quote_id', $quote->id)
->whereNotIn('id', array_keys(request('quoteItems')))
->get()
->each
->delete();
Automatically deleting NESTED related rows in Laravel 5.4 (Eloquent ORM)
That's because when you delete multiple objects at the same time it doesn't trigger the boot deleting function for each model so you should loop through the objects and delete them one by one:
class Book extends Eloquent
{
public function chapters()
{
return $this->has_many(Chapter::class);
}
protected static function boot() {
parent::boot();
static::deleting(function($book) {
foreach($book->chapters as $chapter){
$chapter->delete();
}
});
}
}
/********************************/
class Chapter extends Eloquent
{
public function subChapters()
{
return $this->has_many(SubChapter::class);
}
protected static function boot() {
parent::boot();
static::deleting(function($chapter) {
foreach($chapter->subChapters as $subChapter){
$subChapter->delete();
}
});
}
}
However my recommendation is to set cascading foreign key relation between the tables so the DBMS is going to delete the related rows automatically, the sample code below shows you how to do it in migration files:
Schema::create('chapters', function (Blueprint $table) {
$table->increments('id');
$table->integer('book_id')->unsigned();
$table->string('title');
$table->timestamps();
$table->foreign('book_id')
->references('id')
->on('books')
->onDelete('cascade')
->onUpdate('cascade');
});
Do the same for subChapters.
Hope It helps...
Related Topics
How to Convert Xml into Array in PHP
How to Convert Json String to Array
PHP Display Image Blob from MySQL
PHP - Should I Call Exit() After Calling Location: Header
Creating Default Object from Empty Value in PHP
PHP Fatal Error: Using $This When Not in Object Context
Passing Base64 Encoded Strings in Url
How to Find Where I Will Be Redirected Using Curl in PHP
Warning: a Non-Numeric Value Encountered
How to Repair a Serialized String Which Has Been Corrupted by an Incorrect Byte Count Length
Return Single Column from a Multi-Dimensional Array
How to Load Classes Based on Pretty Urls in MVC-Like Page
Woocommerce: Auto Complete Paid Orders
How to Let PHP to Create Subdomain Automatically For Each User