skip to Main Content

I encountered an error when the user registers, everything is ok and works perfectly, but when the user registers again with the same previous data, it shows this error:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry ‘123456789’ for key ‘users.users_phone_unique’

and i have no ideo what is wrong in these codes
i’m using laravel 10

this is my register controller

namespace AppHttpControllersAuth;

use AppHttpControllersController;
use AppProvidersRouteServiceProvider;
use AppModelsUser;
use IlluminateFoundationAuthRegistersUsers;
use IlluminateSupportFacadesHash;
use IlluminateSupportFacadesValidator;

class RegisterController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use RegistersUsers;

    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return IlluminateContractsValidationValidator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'min:10'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
            'phone' => ['required', 'string', 'max:11'],
        ]);
    }


    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return AppModelsUser
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'phone' => $data['phone'],
            'password' => Hash::make($data['password']),
        ]);
    }
}

this is my user.php

namespace AppModels;

// use IlluminateContractsAuthMustVerifyEmail;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;
use LaravelSanctumHasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'phone',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'phone',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
        'password' => 'hashed',
    ];
}

this is my create user table migration

use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('password');
            $table->string('phone')->unique();
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('users');
    }
};

2

Answers


  1. In your controller you’re not validating the uniqueness of the phone number, hence the data is "passed down" to the DB level, and then it fails because of the violated unique constraint.

    You should add a unique validation rule in your RegisterController in order to fail as soon as the form is sent.

    For example:

    'phone' => ['required', 'string', 'max:11','unique:users']
    
    Login or Signup to reply.
  2. I’m gonna suggest a different approach which is considered to be a better practice for validation.

    1. run php artisan make:request CreateUserRequest, the CreateUserRequest file will be created in /app/Http/Requests directory.
    2. edit the file according to your needs, for example:
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, IlluminateContractsValidationRule|array|string>
     */
    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'min:10'],
            'phone' => ['required', 'string', 'max:11','unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
            /**
             * or if you want to accept complex passwords add `use IlluminateValidationRulesPassword;`
             * on top of the `CreateUserRequest` and then use the following rule instead
             */
            'password' => [
                'required', 'confirmed', 
                Password::min(8)->letters()->mixedCase()->numbers()->symbols()
            ],
        ];
    }
    
    1. for a custom message in case of a failed validation you can add the following method to your CreateUserRequest class:
    /**
     * Set proper error messages for failed validations
     *
     * @return array<string>
     */
    public function messages() {
        return [
            'password.required' => 'my friendly message to the user',
        ];
    }
    

    You need to modify your controller accordingly, for more information take a look at Form Validation Docs.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search