Automatically Deleting Related Rows in Laravel (Eloquent Orm)

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

  1. You have a typo. Try

MyTable::whereDate( 'created_at', '<=', now()->subDays(30))->delete();


  1. 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



Leave a reply



Submit