Laravel 10中如何实现order_number与part_number组合唯一性验证?
Laravel 10 实现order_number与part_number联合唯一验证
要实现同一order_number可对应不同part_number,但order_number+part_number的组合不能重复的验证规则,可通过以下方式落地:
1. 控制器内直接验证
创建场景
使用Rule::unique配合闭包指定联合验证条件:
use Illuminate\Validation\Rule; // 验证请求参数 $validatedData = $request->validate([ 'order_number' => [ 'required', Rule::unique('你的数据表名')->where(function ($query) use ($request) { return $query->where('part_number', $request->part_number); }), ], 'part_number' => 'required', ]);
替换你的数据表名为实际存储该数据的表名(如order_parts)。
更新场景
更新时需排除当前记录,避免自身对比导致验证失败:
use Illuminate\Validation\Rule; use App\Models\OrderPart; // 替换为你的模型类 $orderPart = OrderPart::findOrFail($request->route('id')); // 从路由获取当前记录ID $validatedData = $request->validate([ 'order_number' => [ 'required', Rule::unique('你的数据表名') ->where(fn ($query) => $query->where('part_number', $request->part_number)) ->ignore($orderPart->id), // 忽略当前记录 ], 'part_number' => 'required', ]);
2. 使用表单请求类分离验证逻辑
大型项目推荐用表单请求类拆分验证代码:
创建请求类(StoreOrderPartRequest)
namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rule; class StoreOrderPartRequest extends FormRequest { public function authorize() { return true; // 根据实际权限需求调整 } public function rules() { return [ 'order_number' => [ 'required', Rule::unique('你的数据表名')->where(fn ($query) => $query->where('part_number', $this->part_number)), ], 'part_number' => 'required', ]; } // 自定义错误提示(可选) public function messages() { return [ 'order_number.unique' => '该订单号与零件号的组合已存在,请重新输入。', ]; } }
更新请求类(UpdateOrderPartRequest)
namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rule; use App\Models\OrderPart; class UpdateOrderPartRequest extends FormRequest { public function authorize() { return true; } public function rules() { $orderPart = OrderPart::findOrFail($this->route('orderPart')); // 路由参数名根据实际调整 return [ 'order_number' => [ 'required', Rule::unique('你的数据表名') ->where(fn ($query) => $query->where('part_number', $this->part_number)) ->ignore($orderPart->id), ], 'part_number' => 'required', ]; } }
3. 数据库层面添加联合唯一索引
为避免并发场景下验证层失效,建议在数据表迁移中添加联合唯一索引,从底层保证数据唯一性:
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up() { Schema::table('你的数据表名', function (Blueprint $table) { $table->unique(['order_number', 'part_number']); }); } public function down() { Schema::table('你的数据表名', function (Blueprint $table) { $table->dropUnique(['order_number', 'part_number']); }); } };
添加索引后,若出现重复组合,数据库会抛出异常,可捕获并返回友好提示:
try { // 保存或更新数据逻辑 } catch (\Illuminate\Database\QueryException $e) { if ($e->getCode() === '23000') { // 唯一约束违反错误码 return back()->withErrors(['order_number' => '该订单号与零件号的组合已存在']); } throw $e; }
内容的提问来源于stack exchange,提问作者Mehdi Yaghoubi
相关产品推荐
相关产品推荐

