validationlaravel-9laravel-formrequest

Laravel validation for row uniqueness


Working in Laravel 9, and I am doing my validations in FormRequests.

I have a email_updates table.

I have 3 columns, email, product_uuid, affiliate_uuid, and I am looking to enforce row uniqueness. An email can signup for multiple products, or even the same product from a different affiliate.

There is a shortened scenario of my data. The first 4 rows are valid.

+--------+--------------+----------------+------------+
| email  | product_uuid | affiliate_uuid | created_at |
+--------+--------------+----------------+------------+
| a@a.co | 3ed          | 21c            | 2022-01-01 |
| b@b.co | 46a          | 21c            | 2022-01-01 |
| a@a.co | 46a          | 21c            | 2022-01-01 |
| a@a.co | 46a          | 899            | 2022-01-01 |
+--------+--------------+----------------+------------+

But I need the validator to refuse this row, because trio of a@a.co, 3ed, 21c have already been used before

+--------+--------------+----------------+------------+
| a@a.co | 3ed          | 21c            | 2022-01-01 |
+--------+--------------+----------------+------------+

Here is the validator that I have written so far, but it does not catch my duplicate row

public function rules()
    {
        return [
            'email' => [
                'required|email:rfc,dns|min:5|max:75',
                Rule::unique("email")->where(function ($query) {
                    $query->where("product_uuid", $this->product_uuid)
                        ->where("affiliate_uuid", $this->affiliate_uuid);
                })
            ],
        ];
    }

The Laravel docs do not seem to address my situation https://laravel.com/docs/9.x/validation#rule-unique

I am sure that it is something simple but what am I missing here?


Solution

  • Well it was something simple and frankly dumb! I had tried so many things, that I had several broken things throughout my code. After cleaning them out, it came down to this. Using my attempt or @Osama Alma's answer broke with this error Method Illuminate\Validation\Validator::validateRequired|email does not exist.

    I started a new question to learn how to chain these things together. Laravel merge eloquent validation rule with a Rule::

    A comment on this question gave me the answer. Method Illuminate\Validation\Validator::validateRequired|min does not exist

    You can't use a mix of | and rule

    This code is validating all three, and will allow saving only if the combination of all three are unique

    public function rules()
    {
        return [
            'email' => [
                'required', 'email:rfc,dns', 'min:5', 'max:75',
                Rule::unique("email")->where(function ($query) {
                    $query->where("product_uuid", $this->product_uuid)
                        ->where("affiliate_uuid", $this->affiliate_uuid);
                })
            ],
        ];
    }