Rule::notIn([]) - is not catching the duplicate entry?

Viewed 84

Rule::notIn([]) - is not catching the duplicate entry? is not working for me?

I have a group of people that I don't want to enter the same email address. if a new member joins, they need to enter a unique email address for that group. [$this->familyEmails] holds the email already in the group. It is a one dimensional array. Here is the result of two dd() calls.

enter image description here

enter image description here

And the Rules function (notice that the dd() calls that produced the output in the above graphics is commented out:

    public function rules(){
        
//dd('family emails',$this->familyEmails);

        $w = [];
        foreach($this->familyEmails as $femail){
            if($femail != $this->email && array_search(strtolower($femail),$w)==null)
                $w[] = strtolower($femail);
        }

// dd(['rules_array'=>$w]);

        return [
            'email' => ['nullable','string', 'email', 'max:255',Rule::notIn($w)],

        ];

    }

and the Custom Messages function

public function customMessages(){
        return [
            
            'email.string' => 'Email Address: The email you entered is not a proper email address; please change.',
            'email.email' => 'Email Address: The email you entered is not a proper email address; please change.',
            'email.max' => 'Email Address: The email you entered is too long; please change.',
            'email.not_in' => 'This email address is already used in the family.  Please enter another Email Address',
            
        ];
    }

I also have an updated() function which validates data entered on the fly

public function updated($propertyName){

       $data =  $this->validateOnly($propertyName, $this->rules(), $this->customMessages());
        $this->resetErrorBag($propertyName);
        $this->changesMade = true;
//dd(['data'=>$data,'rules'=>$this->rules()]);
    }

After I enter in an email address into the form, the dd() that you see commented out just above produces the following when i enter in an email that is in the notIn rule. The dd() seen just above should not be reached, but it is.

1 Answers

okay, i decided to answer my own question as it may help others.

I was creating the Rule:notIn([]) inside the Rules() function. But that caused problems.

As it seems that the Rules() function (of course) runs everytime you call the validate() helper. the answer was right in front of me.

When I put the loop in the Mount() function, I achieved my objective.

Before I did that, when creating the rules noIn array in the Rules() function it contained "sam@whistle.com". When I went to enter an email address for another person in the group, I entered "sam@whistle.com" .

So when I typed in the duplicate email, the rules() function ran, and recreated the rules array, and used the email that I typed in and it took it out of the rule. I used the $this->email which is the public property on the component. So I had to put it in the mount() function.

As I write this, I realize I need to put the array back in the Rules() function, and reference the model where the email address is stored, not reference the public property on the component that stores the typed in value.

        $w = [];
        foreach($this->familyEmails as $femail){
            if($femail != $this->person->email && array_search(strtolower($femail),$w)==null)
                $w[] = strtolower($femail);
        }

instead of $this->email, I reference the model for the email address.

Related