覆盖required_without_all laravel的单个消息

时间:2019-02-07 06:23:23

标签: php laravel

我一直在Laravel中使用required_without_all至少一个字段。 这是我的规则代码

'rental_company_id'         => 'required_without_all:camper_id,take_over_station_id,returnable_station_id',
'camper_id'                 => 'required_without_all:rental_company_id,take_over_station_id,returnable_station_id',
'take_over_station_id'      => 'required_without_all:rental_company_id,camper_id,returnable_station_id',
'returnable_station_id'     => 'required_without_all:rental_company_id,camper_id,take_over_station_id',

这是我的自定义消息,它将覆盖laravel产生的默认消息

'rental_company_id.required_without_all'                => 'The Rental Companies is required when none of Campers, Takeover stations and Returnable stations are present.',
'camper_id.required_without_all'                        => 'The Campers is required when none of Rental Companies, Takeover stations and Returnable stations are present.',
'take_over_station_id.required_without_all'             => 'The Takeover stations is required when none of Campers, Rental Companies and Returnable stations are present.',
'returnable_station_id.required_without_all'            => 'The Returnable stations is required when none of Campers, Rental Companies and Takeover stations are present.',

不是向用户显示多行错误消息。有什么办法可以将这四个消息总结为单个消息,例如

  

以下季节之一,租赁公司,...必须在场。

谢谢。

4 个答案:

答案 0 :(得分:2)

所以...我不一定推荐这个,但这里有一种快速而肮脏的方法来防止在多个字段上使用 required_without_all 时出现重复的错误消息,目的是“这些字段中至少有一个是必需”类型的规则:

  1. 在控制器中,为您的字段提供自定义相同错误消息(即不要使用 :attribute):
public function foo(Request $request)
{
    $request->validate(
        [
            // the "at least one of these" fields must be grouped together here.
            'field_1' => 'required_without_all:field_2|nullable|etc',
            'field_2' => 'required_without_all:field_1|nullable|etc',
            // etc...
        ],
        [
            'field_1.required_without_all' => 'At least one is required',
            'field_2.required_without_all' => 'At least one is required',
            // etc...
            // If this list of fields is the only time you're using
            // required_without_all, you can just use a single catch-all
            // ['required_without_all' => 'message'] instead
        ]
    );
}
  1. 然后,在循环/编写错误消息时,在您的视图中检查重复的错误消息:
@if ($errors->any())
    <ul>
        @foreach ($errors->all() as $error)
            @if ($error !== ($prevError ?? ''))
                <li>{{ $prevError = $error }}</li>
            @endif
        @endforeach
    </ul>
@endif

PHP 的一个怪癖(?) 是它在变量赋值时返回分配的值,这就是为什么我们的 <li> 项仍然包含“至少需要一个”错误文本的原因。空合并 ?? 只是为了使 foreach 在分配 $prevError 之前不会在第一个循环中中断。

再次...我不确定我是否可以正确推荐这样做 - 有几个原因导致它不是最理想的。但是,如果您需要一种快速而肮脏的方法来实现“至少其中一个”类型规则,您可能会发现它很有用。

答案 1 :(得分:1)

如果您使用表单请求,则可以通过messages()方法执行此操作:

return [
    'required_without_all' => 'One of the field must be present.'
];

如果您使用手动验证器,则可以执行以下操作:

$messages = [
    'required_without_all' => 'One of the field must be present.',
];

$validator = Validator::make($input, $rules, $messages);

编辑:另一种方法是检查您的MessageBag是否包含其中一个字段的错误,然后在您的视图中相应显示另一个。例如:

@if (
    $errors->has('rental_company_id')
    || $errors->has('camper_id')
    || $errors->has('take_over_station_id') 
    || $errors->has('returnable_station_id')
) {
    // display the error message you need
}

诚然,这并不漂亮,但是我似乎找不到另一种方法。

答案 2 :(得分:1)

有一种非常简单的方法可以实现这一点。将规则应用到一个虚构的 ids 字段,然后在 required_without_all 之后包含您希望对其应用验证的所有实际字段。并且只有一个相应的验证消息。

$validator = Validator::make($request->all(), [
            'ids' => 'required_without_all:rental_company_id,camper_id,take_over_station_id, returnable_station_id'
            ], [
            'required_without_all' => 'One of the following Season,Rental companies,... must be present.'
            ]);

答案 3 :(得分:0)

通过添加自定义规则php artisian make:rule AssignDataValidation

解决
/**
 * Determine if the validation rule passes.
 *
 * @param  string  $attribute
 * @param  mixed  $value
 * @return bool
 */
public function passes($attribute, $value)
{
    $isSet = false;
    $input = Input::all();
    foreach (Discount::ASSIGNED_DATA_FIELD as $data){
        if (isset($input[$data])){
            $isSet = true;
            break;
        }
    }
    return $isSet;
}

/**
 * Get the validation error message.
 *
 * @return string
 */
public function message()
{
    return 'One of the following Season, Rental companies,... must be present.';
}

在表单请求中,我有一个重写getValidatorInstance()方法,并在验证后调用以手动添加我的规则,并在带有自定义名称的错误信息包上触发

protected function getValidatorInstance()
{
    $validator = parent::getValidatorInstance();
    $validator -> after(function ($validator){
        $timeDataValidation     = new TimeDataValidation;
        $assignDataValidation   = new AssignDataValidation;
        if (!$timeDataValidation -> passes(TimeDataValidation::FIELD,Discount::TIME_DATA_FIELD)){
            $validator -> errors() -> add(TimeDataValidation::FIELD,$timeDataValidation -> message());
        }
        if (!$assignDataValidation -> passes(AssignDataValidation::FIELD,Discount::ASSIGNED_DATA_FIELD)){
            $validator -> errors() -> add(AssignDataValidation::FIELD,$assignDataValidation -> message());
        }
    });

    return $validator;
}