Laravel表单验证:如何按条件实现product_id的distinct验证
解决同订单下产品ID不重复的验证问题
你当前用的distinct:strict是全局校验所有product_id的唯一性,不管对应的order_id是否相同,所以会出现不同订单下产品ID重复也报错的情况。要实现同一订单ID下产品ID唯一的需求,需要自定义验证逻辑,下面提供两种可行方案:
方案一:使用闭包添加后置验证
直接在验证器后追加自定义检查逻辑,适合一次性场景:
use Illuminate\Support\Facades\Validator; $validator = Validator::make($request->all(), [ 'inputs.*.order_id' => 'required', 'inputs.*.product_id' => 'required', ], [ 'inputs.*.order_id.required' => '订单ID不能为空', 'inputs.*.product_id.required' => '产品ID不能为空', ]); // 追加同订单产品ID唯一性检查 $validator->after(function ($validator) use ($request) { // 按order_id分组 $orderGroups = collect($request->input('inputs'))->groupBy('order_id'); foreach ($orderGroups as $orderId => $items) { $productIds = $items->pluck('product_id')->toArray(); // 检查组内产品ID是否有重复 if (count($productIds) !== count(array_unique($productIds))) { // 全局提示重复问题 $validator->errors()->add('inputs', "订单ID {$orderId} 下存在重复的产品ID"); // 若需精准定位到重复的数组项,替换上面的错误提示为以下代码: // $seenProducts = []; // foreach ($items as $index => $item) { // $productId = $item['product_id']; // if (in_array($productId, $seenProducts)) { // $validator->errors()->add("inputs.{$index}.product_id", "订单ID {$orderId} 下的产品ID {$productId} 重复"); // } // $seenProducts[] = $productId; // } } } }); if ($validator->fails()) { return redirect()->back()->withErrors($validator)->withInput(); }
方案二:自定义验证规则类(适合复用)
如果多个地方需要这个验证逻辑,可以创建自定义规则类:
1. 创建规则类
// app/Rules/UniqueProductPerOrder.php namespace App\Rules; use Illuminate\Contracts\Validation\Rule; use Illuminate\Support\Collection; class UniqueProductPerOrder implements Rule { protected $inputItems; public function __construct($inputItems) { $this->inputItems = $inputItems; } public function passes($attribute, $value) { // 从属性名中提取当前项的索引(比如"inputs.0.product_id"提取出0) $index = explode('.', $attribute)[1]; $currentOrderId = $this->inputItems[$index]['order_id']; // 统计同订单ID下当前产品ID出现的次数 $duplicateCount = collect($this->inputItems) ->where('order_id', $currentOrderId) ->where('product_id', $value) ->count(); // 只允许出现一次 return $duplicateCount === 1; } public function message() { return '同订单下不能存在重复的产品ID'; } }
2. 使用规则类
use Illuminate\Support\Facades\Validator; use App\Rules\UniqueProductPerOrder; $validator = Validator::make($request->all(), [ 'inputs.*.order_id' => 'required', 'inputs.*.product_id' => [ 'required', new UniqueProductPerOrder($request->input('inputs')) ], ]); if ($validator->fails()) { return redirect()->back()->withErrors($validator)->withInput(); }
内容的提问来源于stack exchange,提问作者owf
相关产品推荐
相关产品推荐

