【问题标题】:Laravel 8 - Gracefully Handle Failed Delete RequestsLaravel 8 - 优雅地处理失败的删除请求
【发布时间】:2021-11-24 22:28:09
【问题描述】:
如果用户想要删除一条记录,比如从 Country 表中删除,但它是数据库中其他记录的父项,并且外键受到限制(即我不想级联删除),则删除失败并且抛出未处理的错误。有没有办法避免这种情况并使用请求返回已处理的错误?我有存储和更新记录的请求,但我找不到任何运行验证以防止删除记录的示例。
根据文档,Exists 有一个验证规则,但 Not Exists 没有。我试过了,但它不起作用:
public function rules()
{
return [
'id' => '!exists:states,country_id'
];
}
【问题讨论】:
标签:
laravel
validation
error-handling
request
【解决方案1】:
您可以使用唯一验证。它将验证 states 表中没有任何条目具有该值的 country_id。即使不建议那样使用它也可以工作。
不要忘记更改错误消息,否则将毫无意义。
public function rules()
{
return [
'id' => 'unique:states,country_id'
];
}
【解决方案2】:
检查关系,如果不为空你可以询问用户是否真的要删除这条记录,如果用户接受,你可以删除记录和它的每一个外键
【解决方案3】:
我最终在 YouTube 上找到了 this 教程。他建议使用withCount 来检查删除是否合适:
public function destroy(int $id) {
$country = Country::withCount('states')->findOrFail($id);
if ($country->states_count === 0) {
$country->delete();
return redirect()->route('countries.index')->with('message', 'Country Deleted Successfully');
}
return redirect()->route('countries.index')->with('message', 'Could not delete country ' . $country->name);
}
我也在 Controller 的 index() 函数中这样做:
$countries = Country::query()->withCount('states');
然后在视图中:
@if ($country->states_count === 0)
<form method="POST" action="{{ route('countries.destroy', $country->id) }}">
@csrf
@method('DELETE')
<button class="btn btn-danger">Delete</button>
</form>
@endif