Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使用Laravel Eloquent删除多个记录_Php_Laravel_Laravel 5_Eloquent_Laravel 5.1 - Fatal编程技术网

Php 如何使用Laravel Eloquent删除多个记录

Php 如何使用Laravel Eloquent删除多个记录,php,laravel,laravel-5,eloquent,laravel-5.1,Php,Laravel,Laravel 5,Eloquent,Laravel 5.1,据我所见,这应该很简单 我希望能够从数据库中删除多条记录。我有我想要删除的所有记录的id。我调用资源。使用逗号分隔的id列表销毁路由(id是postgres类型uuid),如下所示: Request URL:http://foo.app/products/62100dd6-7ecf-4870-aa79-4b132e60c904,c4b369f1-d1ef-4aa2-b4df-b9bc300a4ff5 Request Method:DELETE 另一方面,我的控制器操作如下所示: public

据我所见,这应该很简单

我希望能够从数据库中删除多条记录。我有我想要删除的所有记录的
id
。我调用
资源。使用逗号分隔的id列表销毁
路由(
id
是postgres类型
uuid
),如下所示:

Request URL:http://foo.app/products/62100dd6-7ecf-4870-aa79-4b132e60c904,c4b369f1-d1ef-4aa2-b4df-b9bc300a4ff5
Request Method:DELETE
另一方面,我的控制器操作如下所示:

public function destroy($id)
{
    try {
        $ids = explode(",", $id);
        $org->products()->find($ids)->delete();
    }
    catch(...) {
    }
}
这给了我以下错误:

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')
我已验证
find()
正在返回与指定ID匹配的
产品的集合

我错过了什么

附言: 1.型号
产品
与其他型号有几个
关系。
2.
product.destroy
如果我给它一个
id

编辑 我想,我也在试图理解以下两者之间的区别:

$org->products()->find($ids)->delete()


是吗?据我所见,
find
get
都返回
Collections
当您使用find方法时,它将只找到一个ID。您应该使用where来匹配多个ID

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

这样,您将找到具有给定ID的所有产品,并将其全部删除

问题是您正在对一个集合调用
delete()
,而该集合没有该方法

你有几个选择

模型事件

如果您有用于
删除
/
删除
模型事件的事件侦听器,则需要确保以加载然后删除每个模型的方式进行删除

在这种情况下,您可以对获取ID列表的模型使用
destroy
方法。它将为每个id加载一个新模型,然后对其调用
delete()
。正如您在评论中提到的,它不会将删除仅限于组织中的那些产品,因此您需要在将列表传递到
destroy()
方法之前过滤掉这些ID

public function destroy($id)
{
    try {
        $ids = explode(",", $id);
        // intersect the product ids for the org with those passed in
        $orgIds = array_intersect($org->products()->lists('id'), $ids);
        // now this will only destroy ids associated with the org
        \App\Product::destroy($orgIds);
    }
    catch(...) {
    }
}
如果您不特别喜欢这种方法,则需要迭代您的组织产品集合,并分别调用
delete()
。您可以使用标准的
foreach
,也可以对集合使用
每个
方法:

public function destroy($id)
{
    try {
        $ids = explode(",", $id);
        $org->products()->find($ids)->each(function ($product, $key) {
            $product->delete();
        });
    }
    catch(...) {
    }
}
无模型事件

现在,如果您没有任何需要收听的模型事件,事情会简单一些。在这种情况下,您只需在查询生成器上调用
delete()
,它将直接删除记录,而无需加载任何模型对象。因此,您可以获得更干净、性能更好的代码:

public function destroy($id)
{
    try {
        $ids = explode(",", $id);
        // call delete on the query builder (no get())
        $org->products()->whereIn('id', $ids)->delete();
    }
    catch(...) {
    }
}

我也面临这个问题。让
$orgs
包含一些记录作为集合。现在,您可以使用这样的循环轻松删除这些记录-

foreach($orgs as $org) 
{
    $org->delete();
}

如果您创建产品模型,它将帮助您完成这些类型的操作

例如:

模型
Products.php

<?php

namespace App\Http\Models;

use Illuminate\Database\Eloquent\Model;

class Products extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'products';
    protected $primaryKey = 'id';

    protected $fillable = ['name', 'price', 'description'];


}
还可以使用此选项删除带有自定义参数的查询结果

$deletedRows = Products::where('name', 'phones')->delete();

您可以查看Laravel文档

是否有不清楚的地方?特别是
destroy()
方法?我将此作为参考。我看过你提到的文件。使用产品ID调用
Model::destroy
,我感到有点紧张,因为恶意用户可能会删除属于其他
org
orgs
有许多
产品
)。我希望首先查找记录(基于用户所属的组织),然后删除它们。我可以使用for循环(
n
querys)。我还可以使用
delete
查询
in
子句。只是想知道是否有更方便/优雅的东西。@maytham-ɐɥıλɐɯ我还没有解决它。有关我想到的解决方法,请参见上面的评论。问题是,就像下面提到的人一样,您正在对集合而不是实际对象本身调用delete()。使用您的示例,您可以执行以下操作:
$org->products()->find($id)->每个(函数($product){$product->delete();})
实际上,
find()
支持ID数组。这是没有记录,但你可以看看源代码是的,你是对的。它也是这样做的。。。where.find()方法有时不支持多个id,相反,您可以使用findMany($id)。还有一件事,findMany()和find()方法没有delete()方法。您不能同时使用get()和delete()。此外,如果只有一个id,请使用where,这是个坏主意,因为对于每个条目,都会向数据库发送一个新的查询。
<?php

    namespace App\Http\Controllers;

    use App\Http\Models\Products;

    class Products 
    {
        
        public function destroy($id)
        {
            try {
                
                $ids = explode(",", $id);
                //$ids is a Array with the primary keys
                Products::destroy($ids);
            }
            catch(...) {
            }
        }

    }
$deletedRows = Products::where('name', 'phones')->delete();