Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

gmanish's avatar

How to Delete Multiple Records Using Laravel Eloquent

Now this, from what I can see, should have been simple.

I want to be able to delete multiple records from the database. I have the id's of all the records I wish to delete. I call the resource.destroy route using comma separated list of ids (id is of postgres type uuid), like so:

Request URL:http://foo.app/products/62100dd6-7ecf-4870-aa79-4b132e60c904,c4b369f1-d1ef-4aa2-b4df-b9bc300a4ff5
Request Method:DELETE

On the other end, my controller action looks like so:

public function destroy($id)
{
    try {
        $ids = explode(",", $id);
        $org->products()->find($ids)->delete();
    }
    catch(...) {
    }
}

This gives me the following error:

BadMethodCallException in Macroable.php line 81:
Method delete does not exist.

in Macroable.php line 81
at Collection->__call('delete', array()) in ProductsController.php line 251
at Collection->delete() in ProductsController.php line 251
at ProductsController->destroy('62100dd6-7ecf-4870-aa79-4b132e60c904,c4b369f1-d1ef-4aa2-b4df-b9bc300a4ff5')

I have verified that find() is returning a collection of products matching the specified ids.

What am I missing?

PS:

  1. The model Product has several belongsTo relationships with other models.
  2. The product.destroy code works fine if I pass it a single id
0 likes
15 replies
tykus's avatar

An instance of Collection does not have a delete method. You do have a destroy method on an instance of Model which will accept an array of ids.

You could handle this in a couple of ways: (i) use the existing destroy() method in your controller and accept either an id or an array of ids

public function destroy($id)
{
    if (is_array($id)) 
    {
        Product::destroy($id);
    }
    else
    {
        Product::findOrFail($id)->delete();
    }
    // redirect or whatever...
}

(ii) I prefer to route something like this to its own method, i.e. create a new method in the controller, e.g.

public function destroyMany(array $ids)
{
    Product::destroy($ids);
    // redirect or whatever...
}
6 likes
ayekoto's avatar

@Jeffrey Am unable to create new forum thread, the POST button is automatically disabled even when recapcha is marked.

gmanish's avatar

@ayekoto Be sure to add a subject in the subject line. The line is not very obvious, look at the thick colored portion at the top of the page with a blinking cursor.

gmanish's avatar
gmanish
OP
Best Answer
Level 3

@Stirnwendy Giving it to you, as I feel more comfortable passing in an array of id's to:

$org->products()->whereIn('id', $ids)->delete()

This way, a malicious user will not be able to delete products that do not belong to his organization, which he can easily do using Product::destroy().

11 likes
wturrell's avatar

Just so you know, there's also a truncate() method that'll delete all the rows and reset any auto_increment counter.

cgabbanini's avatar

Hi, I'm sorry to be late replying to this question; anyway, since Laravel is a very flexible framework, I found a solution that could suit:

$collection = ModelName::where('condition', 'value')->get(['id']);
ModelName::destroy($collection->toArray());
6 likes
SeongjuneKim's avatar

Thanks to cgabbanini. so helpful. I was just thinking that I can't use destroy function on collection but that's the way to go around..

$collection = ModelName::where('condition', 'value')->get(['id']);
ModelName::destroy($collection->toArray());
hondnl's avatar

gmanish his answer is the best one... Remember ,always check how many queries you run...

His is just one query.. the other ones are multiple queries.

You could also do this with the builder if you wanted to delete the products with a list of userid's

DB::table('products')
 ->join('users','products.user_id' ,'=' ,'users.id')
 ->whereIn('users.id', $explodedUserIds)
 ->delete();
johanchouquet's avatar

Hi,

if you have a Collection from a relationship for example, you can do :

$entities = $user->entities;
$entityIds = $entities->map( function($entity) {
    return [$entity['id']];
});
Entity::whereIn('id', $entityIds)->deleted();

I had the same need and this works fine.

samir94's avatar

Hi, I think you should try this codes

  public static function delete_data(){
        $id=request()->segment(2);
        $sql=InsertModel::where('id',$id)->delete();
    }
kazemimorteza68@gmail.com's avatar
  $id=[4,5,6,7,8,9,10];
$result=myModel::whereIn('id',$id)->delete();
print_r($result);
2 likes
hugronaphor's avatar

Relation also can perform a delete

$this->hasMany(Bit::class)->delete();
1 like
jacques-pienaar's avatar

Late, but found this awesome solution: (each->)

$org->products()->whereIn('id', $ids)->each->delete()
1 like

Please or to participate in this conversation.