Cod*_*oet 9 php laravel eloquent laravel-5 laravel-5.1
从我所看到的,现在这应该很简单.
我希望能够从数据库中删除多个记录.我有id我想删除的所有记录.我resource.destroy使用逗号分隔的id列表(id具有postgres类型uuid)来调用路由,如下所示:
Request URL:http://foo.app/products/62100dd6-7ecf-4870-aa79-4b132e60c904,c4b369f1-d1ef-4aa2-b4df-b9bc300a4ff5
Request Method:DELETE
Run Code Online (Sandbox Code Playgroud)
另一方面,我的控制器动作如下:
public function destroy($id)
{
try {
$ids = explode(",", $id);
$org->products()->find($ids)->delete();
}
catch(...) {
}
}
Run Code Online (Sandbox Code Playgroud)
这给了我以下错误:
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')
Run Code Online (Sandbox Code Playgroud)
我已经验证了find()返回products匹配指定ID 的集合.
我错过了什么?
PS:1.该模型与其他模型Product有几种belongsTo关系.2. product.destroy代码工作正常,如果我通过一个单一id
编辑 我猜,我也试图了解它们之间的区别:
$org->products()->find($ids)->delete()
Run Code Online (Sandbox Code Playgroud)
和
$org->products()->whereIn('id', $ids)->get()->delete()
Run Code Online (Sandbox Code Playgroud)
是什么?从我所看到的,find和get正在返回Collections
pat*_*cus 16
问题是你正在调用delete()一个没有该方法的Collection.
你有两个选择.
模特活动
如果您有deleting/ deletedmodel事件的事件侦听器,则需要确保以每个模型加载然后删除的方式进行删除.
在这种情况下,您可以destroy在采用id列表的模型上使用该方法.它将为每个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(...) {
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不特别喜欢这种方法,则需要迭代您的组织产品集合并delete()单独调用它们.您可以使用标准foreach,也可以each在集合上使用该方法:
public function destroy($id)
{
try {
$ids = explode(",", $id);
$org->products()->find($ids)->each(function ($product, $key) {
$product->delete();
});
}
catch(...) {
}
}
Run Code Online (Sandbox Code Playgroud)
没有模特活动
现在,如果您没有需要倾听的任何模型事件,事情会更容易一些.在这种情况下,您可以只调用delete()查询构建器,它将直接删除记录而不加载任何模型对象.因此,您可以获得更好的性能:
public function destroy($id)
{
try {
$ids = explode(",", $id);
// call delete on the query builder (no get())
$org->products()->whereIn('id', $ids)->delete();
}
catch(...) {
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
如果您创建产品模型,它将帮助您完成这些类型的操作。
例如:
该模型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'];
}
Run Code Online (Sandbox Code Playgroud)
控制器Products.php
您可以使用该destroy方法并将一个或多个主键作为参数传递给它。
<?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(...) {
}
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用此选项通过自定义参数删除查询结果
$deletedRows = Products::where('name', 'phones')->delete();
Run Code Online (Sandbox Code Playgroud)
您可以查看 Laravel 文档https://laravel.com/docs/8.x/eloquent#soft-deleting
| 归档时间: |
|
| 查看次数: |
30288 次 |
| 最近记录: |