【问题标题】:Override single message for required_without_all laravel覆盖 required_without_all laravel 的单个消息
【发布时间】:2019-07-01 05:19:17
【问题描述】:

我一直在使用 required_without_all 作为 laravel 中至少一个必填字段。 这是我的规则代码

'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.',

而不是向用户显示多行错误消息。有什么办法可以把这四条消息总结成一条消息,比如

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

提前致谢。

【问题讨论】:

    标签: php laravel


    【解决方案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.'
                ]);
    

    【讨论】:

      【解决方案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 的一个怪癖(?)是它在变量赋值时返回分配的值,这就是为什么我们的&lt;li&gt; 项目仍将包含“至少一个必需”错误文本。空值合并 ?? 只是为了使 foreach 在分配 $prevError 之前不会在第一个循环中中断。

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

      【讨论】:

        【解决方案3】:

        如果您使用表单请求,您可以在 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
        }
        

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

        【讨论】:

        • 我正在使用表单请求,但我必须将 required_without_all 用于其他字段和其他情况下的相同表单。对不起,我误导了我的信息。我已经编辑了我的问题。
        • 在这种情况下,我不确定从验证者的角度来看是否可以实现。
        • 还有其他方法可以推荐给我吗??
        • 编辑了我的答案以添加一个可能的替代方案。不过,不是它的忠实粉丝。
        【解决方案4】:

        通过添加自定义规则php artisan 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;
        }
        

        【讨论】:

          猜你喜欢
          • 2018-01-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-28
          • 1970-01-01
          • 2020-04-16
          相关资源
          最近更新 更多