Laravel 10 - 始终验证字段,即使该字段不在请求中

问题描述 投票:0回答:1

我有以下验证部分:

'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

php laravel laravel-10 laravel-validation
1个回答
0
投票

为了简单起见,我将使用 eloquent 的关系

class Company extends Model
{
    public function places()
    {
        return $this->hasMany(Place::class);
    }
}

在验证类中

public function validate(string $attribute, mixed $values, Closure $fail): void
{
    // Retrieve the company with its associated places
    $company = Company::with(['places:id,company_id'])
        ->firstWhere('id', $this->data['company_id']);

    // If the company doesn't have places, the validation will pass
    if ($company->places->count() === 0) {
        return;
    }

    if (empty($values)) {
        $fail('Please select a place associated with the company.');
    }

    $placesIds = $company->places->pluck('id')->toArray();
    $difference = array_diff($values, $placesIds);

    // If one or more selected places are not associated with the company,
    // the validation will fail
    if (! empty($difference)) {
        $fail('One or more selected places are not associated with the company.');
    }

    // If the company has places and the selected places are associated with the company,
    // the validation will pass

}
© www.soinside.com 2019 - 2024. All rights reserved.