Skip to content
Advertisement

Unique validation with 2 columns – Laravel 8.x

I’ve been trying make my validation so that an extension must be unique to it’s own company but not to other companies. Here is my DB table:

            $table->id();
            $table->foreignId('user_id')->constrained(); 
            $table->foreignId('account_id')->constrained()->onDelete('cascade'); 
            $table->string('first_name')->nullable();
            $table->string('last_name')->nullable();
            $table->string('email');
            $table->string('extension');
            $table->string('password')->nullable();
            $table->string('user_type')->default('user');
            $table->timestamps();
            $table->unique(['extension', 'account_id'], 'unique_extension');

And my validation rule looks like this:

public function rules()
    {
        return [
            'editExtension.first_name' => 'required|max:255',
            'editExtension.last_name' => 'required|max:255|',
            'editExtension.email' => ['required', 'email','max:255', Rule::unique('account_users', 'email')->ignore($this->editExtension->id)],
            'editExtension.extension' => ['required', 'numeric', Rule::unique('account_users', 'extension', $this->client_id)->ignore($this->editExtension->id)],
            'editExtension.password' => 'required|max:255',
            'editExtension.user_type' => 'required|in:user,admin',
        ];
    }

But still I got errors saying that the extension number is already taken. It seems that the Unique rule doesn’t accept multiple columns, only one. Is this true?

How can I fix this?

Advertisement

Answer

Forcing A Unique Rule To Ignore A Given ID:

UPDATING AN EXISTING RECORD.

“account_users” => Table name.

“account_id”, “extension” => The 2 fields to check for uniqueness.

ID of currently edited row here. => The id (primary key) to ignore. (The currently updated/edited table row id.)

Rule::unique("account_users")->where(
                    function ($query) use ($request) {
                        return $query->where(
                            [
                                ["account_id", "=", $request->account_id],
                                ["extension", "=", $request->extension]
                            ]
                        );
                    })->ignore(/* ID of currently edited row here. */)

CREATING A NEW RECORD.

Rule::unique("account_users")->where(
                    function ($query) use ($request) {
                        return $query->where(
                            [
                                ["account_id", "=", $request->account_id],
                                ["extension", "=", $request->extension]
                            ]
                        );
                    })

Addendum

By default, the unique rule will check the uniqueness of the column matching the name of the attribute being validated. However, you may pass a different column name as the second argument to the unique method:

Rule::unique("account_users", "extension")->where(...)
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement