0

I am importing excel file to collections using laravel-excel package. I am trying to validate the date field reporting_date such that it is after_or_equal two other date fields registered_date and analysis_date. With only one after_or_equal date field all this is working fine. I am dynamically populating the rules and custom messages array. The rules are applying correctly but I have problem overriding the default message by the custom message for this particular validation and instead the default message is displayed.

public function collection(Collection $rows)
{
  $data = $rows->toArray();
  $rules = [Some static rules defined];

  $messages = [];
        
        
  foreach ($data as $key => $val){
     /*Adding [complex/]conditional rules and messages.*/
     ...
     ...
    if(!empty($val['reporting_date'])){
            $rules = array_merge($rules, [$key.'.reporting_date' => ['sometimes', 'nullable', 'date', 'after_or_equal:'.$key.'.registered_date,', 'after_or_equal:'.$key.'.analysis_date']]);

            $messages["$key.reporting_date.date"] = "Error on row: <strong>".($key+2)."</strong>. The reporting_date <strong>".(Arr::exists($val, "reporting_date")?$val['reporting_date']:"").
                    "</strong> is not a valid date.";
            
            /****These messages are not overriding the default message.****/  
            $messages["$key.reporting_date.after_or_equal.$key.registered_date"] = "Error on row: <strong>".($key+2)."</strong>. The reporting_date <strong>".(Arr::exists($val, "reporting_date")?$val['reporting_date']:"").
                    "</strong> must be a date after or equal to registered_date <strong>".(Arr::exists($val, "registered_date")?$val['registered_date']:"").
                    "</strong>.";
            
            $messages["$key.reporting_date.after_or_equal.$key.analysis_date"] = "Error on row: <strong>".($key+2)."</strong>. The reporting_date <strong>".(Arr::exists($val, "reporting_date")?$val['reporting_date']:"").
                    "</strong> must be a date after or equal to analysis_date <strong>".(Arr::exists($val, "analysis_date")?$val['analysis_date']:"").
                    "</strong>.";
    ...
    ...
            
            
    }
  }  
}

The message I am getting instead is

The 0.reporting_date must be a date after or equal to 0.registered_date.
The 0.reporting_date must be a date after or equal to 0.analysis_date.

The validation rule:

"0.reporting_date" => array:5 [▼
      0 => "sometimes"
      1 => "nullable"
      2 => "date"
      3 => "after_or_equal:0.registered_date,"
      4 => "after_or_equal:0.analysis_date"
    ]

I suspect that I am not assigning the message to the correct array key and hence I am not seeing the custom message. Right now it is assigned like this and I would like this message to be displayed.

"0.reporting_date.after_or_equal.0.registered_date" => "Error on row: 2. The reporting_date 2020-09-08 must be a date after or equal to registered_date 2020-09-12."
"0.reporting_date.after_or_equal.0.analysis_date" => "Error on row: 2. The reporting_date 2020-09-08 must be a date after or equal to analysis_date 2020-09-14."

Also on debugging the error message.

dd($validator->errors()); 
0.reporting_date" => array:2 [▼
      0 => "The 0.reporting_date must be a date after or equal to 0.registered_date."
      1 => "The 0.reporting_date must be a date after or equal to 0.analysis_date."
    ]
1
  • When validating, usually, at first error you'll get redirected back. To avoid this you may split validation machanics in 2 or more phases. Not sure you get this but you can do something like: validate->this. then validate-> that.... then save/update stuff. Commented Jan 25, 2021 at 17:17

1 Answer 1

1

To specify a custom error message only for a specific attribute, you specify the attribute's name first, followed by the rule:

field.rule => message

Like

$messages = [
    'email.required' => 'We need to know your email address!',
];

So I had to check if 0.reporting_date is after_or_equal 0.registered_date and 0.analysis_date. I had the rules set up like:

"0.reporting_date" => array:5 [▼
      0 => "sometimes"
      1 => "nullable"
      2 => "date"
      3 => "after_or_equal:0.registered_date,"
      4 => "after_or_equal:0.analysis_date"
    ]

When one of the validations of after_or_equal failed, I could override the messages like

0.reporting_date.after_or_equal => "custom message"

But when both after_or_equal:0.registered_date and after_or_equal:0.analysis_date failed, I thought it was possible to write custom messages for individual cases like below which would have been ideal.

"0.reporting_date.after_or_equal.0.registered_date" => "custom message1"
"0.reporting_date.after_or_equal.0.analysis_date" => "custom message2"

But that did not work and I had to do a bit of hack by manually comparing the dates and then appending both messages which solved the problem.

if(!(Carbon::parse(0.reporting_date)->gte(Carbon::parse(0.registered_date)) && Carbon::parse(0.reporting_date)->gte(Carbon::parse(0.analysis_date)))){
    0.reporting_date.after_or_equal => "custom message1"."custom message2"
}

I would like to see if there are other better approaches.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.