You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 11:17:37