Laravel验证规则:同一delivery_id下counter_num不可重复是否可行?
问题描述
我有两张数据表:
deliveries:字段为id、namedelivery_items:字段为id、delivery_id、name、counter_num
需求是设置验证规则:同一个delivery_id对应的记录中,counter_num不能重复,但不同delivery_id之间的counter_num可以重复。
目前我有一条全局唯一的验证规则:
public function rules(): array { return [ 'counter_num' => 'required|unique:delivery_items,counter_num' ]; }
我尝试写了如下联合验证规则,请问这条规则是否可行?
public function rules(): array { return [ 'counter_num' => 'required|unique:delivery_items,counter_num,delivery_id' ]; }
数据表示例:
| id | delivery_id | counter_num |
|---|---|---|
| 1 | 1 | 123 |
| 2 | 1 | 124 |
| 3 | 2 | 124 |
| 4 | 2 | 125 |
| 5 | 2 | 126 |
规则分析与修正
你写的这条联合验证规则不可行,因为Laravel的unique验证器参数顺序不符合需求。
unique验证器的参数逻辑是:unique:表名,字段名,忽略ID,忽略字段名,额外条件字段1,额外条件值1,...,你当前的写法把delivery_id当成了「忽略字段」,而非限定范围的条件,无法实现同delivery_id下counter_num唯一的需求。
正确的实现方式是通过额外条件限定验证范围,以下两种写法都可以:
写法一:字符串格式
public function rules(): array { return [ 'counter_num' => 'required|unique:delivery_items,counter_num,NULL,id,delivery_id,' . $this->delivery_id ]; }
参数说明:
NULL:表示不忽略任何记录(更新场景下可替换为当前记录ID,避免验证自身)id:默认忽略字段(此处无实际作用,填主键即可)delivery_id:用于限定范围的字段名$this->delivery_id:当前请求或模型实例中的delivery_id值
写法二:数组闭包格式(推荐,可读性更强)
use Illuminate\Validation\Rule; public function rules(): array { return [ 'counter_num' => [ 'required', Rule::unique('delivery_items')->where(function ($query) { return $query->where('delivery_id', $this->delivery_id); }) ] ]; }
闭包写法更灵活,能应对复杂的条件组合。如果是更新场景,需要排除当前记录,可追加->ignore($this->route('delivery_item')->id)。
内容的提问来源于stack exchange,提问作者dbudimir
相关产品推荐
相关产品推荐

