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

Laravel 10:请求无places字段时仍需验证该字段的实现方法

问题与解决方案

验证规则代码片段

'places' => [
    new CompanyHasPlacesRule,
],

验证类代码

public function validate(string $attribute, mixed $value, Closure $fail): void
{
    $company = DB::table('companies')
        ->select('companies.id', DB::raw('GROUP_CONCAT(places.id) as placeIDs'))
        ->join('places', 'companies.id', '=', 'places.company_id')
        ->where('companies.id', $this->data['company_id'])
        ->groupBy('companies.id')
        ->first();
    
    if (! $company?->placeIDs && $value === null) {
        return;
    }

    if ($company?->placeIDs && $value === null) {
        $fail('Please select place associated with the company.');
    }

    if ($value && $company->placeIDs) {

        $difference = array_diff($value, explode(',', $company->placeIDs));

        if (! empty($difference)) {
            $fail('Selected company does not have this place assigned.');
        }

        return;
    }

    $fail('Selected company does not have this place assigned.');

}

问题描述

公司并非总会关联场所,但如果公司有场所,则必须选择一个或多个places字段;而判断公司是否有场所的逻辑在验证规则内部。请问如何实现即使请求中不存在places字段,仍对该字段执行验证?


解决方案

Laravel 默认不会对请求中不存在的字段执行验证规则,要强制触发验证,只需按以下步骤处理:

  1. 添加present验证规则
    修改验证规则定义,为places字段添加present规则。这个规则会确保无论请求中是否包含该字段,都会触发后续的自定义验证逻辑,此时字段值会被设为null:

    'places' => [
        'present',
        new CompanyHasPlacesRule,
    ],
    
  2. 优化验证类逻辑(可选)
    你的现有逻辑已经能处理$value === null的场景,但可以合并冗余分支,让代码更简洁:

    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        $company = DB::table('companies')
            ->select('companies.id', DB::raw('GROUP_CONCAT(places.id) as placeIDs'))
            ->join('places', 'companies.id', '=', 'places.company_id')
            ->where('companies.id', $this->data['company_id'])
            ->groupBy('companies.id')
            ->first();
        
        $hasPlaces = !empty($company?->placeIDs);
        
        // 公司无关联场所,直接通过验证
        if (!$hasPlaces) {
            return;
        }
        
        // 公司有场所但未选择任何地点
        if ($value === null || (is_array($value) && empty($value))) {
            $fail('Please select place associated with the company.');
        }
        
        // 校验所选地点是否属于该公司
        $allowedPlaces = explode(',', $company->placeIDs);
        $difference = array_diff((array)$value, $allowedPlaces);
        
        if (!empty($difference)) {
            $fail('Selected company does not have this place assigned.');
        }
    }
    

内容的提问来源于stack exchange,提问作者Sasha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 03:22:53