Laravel自定义验证规则:同机构下Profile名称需唯一
实现Laravel自定义验证规则:同组织下Profile名称唯一
步骤1:生成自定义验证规则类
运行Artisan命令创建规则文件:
php artisan make:rule UniqueNamePerOrg
步骤2:编写验证逻辑
打开app/Rules/UniqueNamePerOrg.php,替换为以下代码:
<?php namespace App\Rules; use App\Models\Profile; use Illuminate\Contracts\Validation\Rule; class UniqueNamePerOrg implements Rule { protected $ignoreProfile; // 构造函数:接收要排除的Profile实例(更新场景使用) public function __construct($ignoreProfile = null) { $this->ignoreProfile = $ignoreProfile; } public function passes($attribute, $value) { $contractId = request()->input('contract_id'); // 先校验contract_id有效性(可选,避免无效关联查询) if (!\App\Models\Contract::where('id', $contractId)->exists()) { return false; } // 构建查询:匹配同组织下同名的Profile $query = Profile::whereHas('contract', function ($q) use ($contractId) { // 用子查询获取当前合同对应的组织ID,减少数据库请求 $q->where('org_id', function ($subQuery) use ($contractId) { $subQuery->select('org_id')->from('contracts')->where('id', $contractId); }); })->where('name', $value); // 更新场景下,排除当前Profile自身 if ($this->ignoreProfile) { $query->where('id', '!=', $this->ignoreProfile->id); } // 无匹配结果则验证通过 return $query->count() === 0; } public function message() { return '该名称在当前组织下已存在,请更换其他名称。'; } }
步骤3:在验证流程中使用规则
场景1:创建Profile时
在控制器或表单请求类中调用:
use App\Rules\UniqueNamePerOrg; // ... $validatedData = request()->validate([ 'contract_id' => 'required|exists:contracts,id', 'name' => ['required', 'string', new UniqueNamePerOrg()], // 其他字段的验证规则 ]);
场景2:更新Profile时
传入当前要更新的Profile实例,避免自身名称冲突:
use App\Rules\UniqueNamePerOrg; use App\Models\Profile; // ... $profile = Profile::findOrFail($id); $validatedData = request()->validate([ 'contract_id' => 'required|exists:contracts,id', 'name' => ['required', 'string', new UniqueNamePerOrg($profile)], // 其他字段的验证规则 ]);
内容的提问来源于stack exchange,提问作者PttRulez
相关产品推荐
相关产品推荐

