Laravel 5.8删除数据报Collection::delete方法不存在错误怎么解决
问题产生原因
- 你调用
get()方法查询数据时,返回的结果是Illuminate\Database\Eloquent\Collection集合实例,而非Eloquent模型实例,集合类本身没有封装delete()方法,只有单个模型实例和查询构造器才支持调用delete()方法。 - 额外逻辑问题:
get()方法无论是否命中数据都会返回集合实例,永远不会等于NULL,你写的if($subscribe != NULL)判断完全不会生效。
解决方案
以下三种方案可根据业务场景选择:
方案1:直接通过查询构造器删除(性能最优,不需要先查数据)
不需要先调用get()获取数据,直接在查询构造器后调用delete()即可,修改控制器代码如下:
public function destroy(Request $request, Wallet $wallet) { UserWallet::where('wallet_id',$wallet->id)->delete(); UserWalletTransaction::where('wallet_id', $wallet->id)->delete(); $wallet->delete(); return redirect(url('admin/wallets/index')); }
这种方式直接执行数据库删除语句,不需要把数据加载到内存,性能最高,适合不需要提前处理关联数据的场景。
方案2:遍历集合逐个删除(需要先获取数据做业务校验的场景)
如果你确实需要先查询出关联数据做其他业务判断,再执行删除,可以遍历集合逐个调用模型的delete()方法:
public function destroy(Request $request, Wallet $wallet) { $subscribes = UserWallet::where('wallet_id',$wallet->id)->get(); $transactions = UserWalletTransaction::where('wallet_id', $wallet->id)->get(); // 可在此处添加对$subscribes、$transactions的业务校验逻辑 foreach ($subscribes as $item) { $item->delete(); } foreach ($transactions as $item) { $item->delete(); } $wallet->delete(); return redirect(url('admin/wallets/index')); }
这种方式会触发单个模型的删除事件,适合依赖模型事件处理关联逻辑的场景。
方案3:配置模型关联删除(最符合Laravel规范的写法)
你可以直接在Wallet模型中定义关联关系,同时配置级联删除,控制器只需要删除Wallet实例即可自动清理关联数据:
首先在Wallet模型中添加关联定义:
// 关联用户钱包表 public function userWallets() { return $this->hasMany(UserWallet::class); } // 关联交易表 public function userWalletTransactions() { return $this->hasMany(UserWalletTransaction::class); } // 模型启动方法中注册删除事件 protected static function booted() { static::deleting(function ($wallet) { $wallet->userWallets()->delete(); $wallet->userWalletTransactions()->delete(); }); }
控制器的destroy方法可以简化为:
public function destroy(Request $request, Wallet $wallet) { $wallet->delete(); return redirect(url('admin/wallets/index')); }
内容的提问来源于stack exchange,提问作者Pouya Vaghefi
相关产品推荐
相关产品推荐

