Search code examples
laravelvalidationrequestuniquemessage

Laravel "unique" Custom Message Validation in Form Request Validation


I created the Form Request Validation and I have problem to customize the custom validation message for multiple "unique" validator

I created the function like the documentation says, however it not showing my message instead the default one (email: ["The email has already been taken."])

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'email' => "required|string|email|unique:table1,email|unique:table2,email"
    ];
}

/**
 * Get the error messages for the defined validation rules.
 *
 * @return array
 */
public function messages()
{
    return [
        "email.unique:table1,email" => "Error message for table 1",
        "email.unique:table2,email" => "Completely different error message for table 2"
    ];
}

I can output the custom result if I use:

public function messages()
{
    return [
        "email.unique" => "Same message for table 1 and table 2 error messages" 
    ];
}

however this isn't what i want, i want to custom the message separately, how I supposed to do?


Solution

  • You can't use this:

    public function messages()
    {
        return [
            "email.unique:table1,email" => "Error message for table 1",
            "email.unique:table2,email" => "Completely different error message for table 2"
        ];
    }
    

    You can't discriminate the two unique rules by their table names.

    What i suggest:

    You can create your own custom validation rules (check the docs) for applying unique:table1 and unique:table2, named differently (ex: unique_first_table and unique_second_table). Then you can do this:

    $messages = [
        'email.unique_table_1' => 'Error message for table 1',
        'email.unique_table_2' => 'Completely different error message for table 2',
    ];
    

    The custom validation rules:

    Within your AppServiceProvider file, put this code:

    use Validator;
    
    //In the boot method:
    Validator::extend('unique_table_1', function ($attribute, $value, $parameters, $validator) {
        if(ModelFirstTable::where('email', $value)->count() > 0)
            return false;
        return true;
    });
    
    Validator::extend('unique_table_2', function ($attribute, $value, $parameters, $validator) {
        if(ModelSecondTable::where('email', $value)->count() > 0)
            return false;
        return true;
    });
    

    ModelFirstTable and ModelSecondTable must be replaced with the model name of your first and second table, respectively.

    Then, use it in your form request:

    public function rules()
    {
        return [
            'email' => "required|string|email|unique_table_1|unique_table_2"
        ];
    }
    
    public function messages()
    {
         return [
            "email.unique_table_1" => "Error message for table 1",
            "email.unique_table_2" => "Completely different error message for table 2"
        ];
    }
    

    Hope it helps.