Laravel更新时featured_order字段排除重复非空值的验证方案咨询
问题描述
我有一个名为featured_order的字段,取值为单个整数(1、2、3……)或null。现有数据如下:
| Name | Featured Order |
|---|---|
| A | 1 |
| B | 2 |
| C | null |
| D | 3 |
需求:执行UPDATE操作时,满足以下任一条件则更新成功:
featured_order字段值无变化;- 新值与其他数据的非
null值均不重复。
举例:更新数据B(原featured_order为2)时,新值设为2、4、5等均可成功;若设为1或3则触发验证错误。
尝试过的无效方法
- 获取排除
null和自身值的featured_order数组:
$data = Model::where('featured_order', '!=', null) ->where('featured_order', '!=', $this->featured_order) ->pluck('featured_order');
随后使用not_in验证:
'featured_order' => "not_in:$data"
- 使用
unique验证:
'featured_order' => "unique:products_and_solutions,featured_order,$data"
解决方案
方法一:正确使用Laravel内置unique验证规则
Laravel的unique规则支持忽略当前记录,还能添加额外条件过滤null值,完全匹配需求:
use Illuminate\Validation\Rule; // 验证规则定义 'featured_order' => [ 'nullable', 'integer', Rule::unique('products_and_solutions', 'featured_order') ->ignore($this->id) // 排除当前更新的记录,允许值与原字段一致 ->whereNotNull('featured_order') // 仅检查非null的featured_order值 ],
方法二:自定义验证规则(应对更复杂场景)
如果默认规则无法满足特殊逻辑,可自定义验证规则:
- 在
AppServiceProvider的boot方法中注册规则:
use Illuminate\Support\Facades\Validator; public function boot() { Validator::extend('unique_featured_order', function ($attribute, $value, $parameters, $validator) { // 允许值为null if (is_null($value)) { return true; } // 统计是否存在其他非null的重复值 $duplicateCount = \App\Models\YourModel::where('featured_order', $value) ->where('id', '!=', $parameters[0]) // 排除当前记录 ->whereNotNull('featured_order') ->count(); return $duplicateCount === 0; }); }
- 在验证时使用该自定义规则:
'featured_order' => [ 'nullable', 'integer', "unique_featured_order:{$this->id}" ],
内容的提问来源于stack exchange,提问作者Wojak McWagies
相关产品推荐
相关产品推荐

