【问题标题】:How to handle duplicate entry for email error?如何处理电子邮件错误的重复输入?
【发布时间】:2019-12-07 21:57:26
【问题描述】:

我有一个表单,管理员可以在其中添加用户。当我使用数据库中存在的一些电子邮件提交表单时,我收到错误提示

SQLSTATE[23000]:违反完整性约束:1062 键“users_email_unique”的重复条目“mail@mail.com”

我想避免该错误,而是获得例如警告“邮件被占用”或类似的东西。任何帮助表示赞赏。这是我的代码。

用户控制器.php

public function store(StoreUserInfo $data)
{
    $data->validated();

    $user = User::create([
        'first_name' => $data['first_name'],
        'last_name' => $data['last_name'],
        'email' => $data['email'],
        'password' => Hash::make($data['password']),
        'city' => $data['city']
    ]);

     return redirect()
        ->route('admin.users')
        ->with('message', 'User created successfully');
}

StoreUserInfo.php

public function rules()
{
    $emailid = (Auth::user()->roles()->first()->name == 'admin')
        ? (isset($this->user->id)?$this->user->id:Auth::user()->id) : Auth::user()->id;

    return [

        'first_name' => ['required', 'string', 'max:255'],
        'last_name' => ['required', 'string', 'max:255'],
        'email' => ['required', 'string', 'email', 'max:255', 'unique:users,email,' . $emailid],
        'city' => ['required', 'exists:cities,city']
    ];
}

register.blade.php

<form id="form"method="POST" action="{{ route('admin.user.store') }}">

    @csrf

    <div class="form-group row">
        <label for="first_name" class="col-md-4 col-form-label text-md-right">{{ __('First Name') }}</label>

        <div class="col-md-6">
            <input id="name" type="text" class="form-control @error('first_name') is-invalid @enderror" name="first_name" value="{{ old('first_name') }}" required autocomplete="first_name" autofocus>

            @error('first_name')
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $message }}</strong>
                </span>
            @enderror
        </div>
    </div>

    <div class="form-group row">
            <label for="last_name" class="col-md-4 col-form-label text-md-right">{{ __('Last Name') }}</label>

            <div class="col-md-6">
                <input id="name" type="text" class="form-control @error('last_name') is-invalid @enderror" name="last_name" value="{{ old('last_name') }}" required autocomplete="last_name" autofocus>

                @error('last_name')
                    <span class="invalid-feedback" role="alert">
                        <strong>{{ $message }}</strong>
                    </span>
                @enderror
            </div>
        </div>

    <div class="form-group row">
        <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

        <div class="col-md-6">
            <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">

            @error('email')
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $message }}</strong>
                </span>
            @enderror
        </div>
    </div>

    <div class="form-group row">
        <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

        <div class="col-md-6">
            <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">

            @error('password')
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $message }}</strong>
                </span>
            @enderror
        </div>
    </div>

    <div class="form-group row">
        <label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>

        <div class="col-md-6">
            <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
        </div>
    </div>
    <div class="form-group row">
            <label for="city" class="col-md-4 col-form-label text-md-right">{{ __('Select City') }}</label>

            <input name="city" list="result" id="input" value="{{ old('city') }}" class="form-control  @error('city') is-invalid @enderror col-sm-6 custom-select custom-select-sm"required autocomplete="city">
            <datalist id="result">
            </datalist>

            @error('city')
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $message }}</strong>
                </span>
            @enderror
    </div>

</form>

用户表

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('first_name');
        $table->string('last_name');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->string('city');
        $table->rememberToken();
        $table->timestamps();
    });
}

【问题讨论】:

    标签: php laravel validation


    【解决方案1】:

    你可以这样检查。

    public function store(StoreUserInfo $data)
    {
        $data->validated();
    
      $email = User::where('email',$data['email'])->first();
     if($email){
        return redirect()
        ->route('admin.users')
        ->with('message', 'Email is already exists.');
     }
    
    $user = User::create([
        'first_name' => $data['first_name'],
        'last_name' => $data['last_name'],
        'email' => $data['email'],
        'password' => Hash::make($data['password']),
        'city' => $data['city']
    ]);
    
     return redirect()
        ->route('admin.users')
        ->with('message', 'User created successfully');
    }
    

    【讨论】:

      【解决方案2】:

      这可以通过几种不同的方式处理,但为了可读性和将查询数量保持在最低限度,我会将 create() 更改为 firstOrCreate() 并使用 wasRecentlyCreated 内置的 laravel 来查看用户是否是新的。

       $user = User::firstOrCreate([
              'email' => $data['email'],
          ], [
              'password' => Hash::make($data['password']),
              'city' => $data['city']
              'first_name' => $data['first_name'],
              'last_name' => $data['last_name'],
      ]);
      

      由于您可以将两个数组传递给firstOrCreate,因此它将返回与电子邮件匹配的第一条记录,或者使用您传递给它的属性创建一个新记录。然后,您可以使用wasRecentlyCreated 检查它是新记录还是已经存在。

      if($user->wasRecentlyCreated){
          return whatever you need if it is a new user 
      }
      else{
         return user was already in the database
      }
      

      【讨论】:

        【解决方案3】:

        您可以使用 Rule 创建验证器 https://laravel.com/docs/5.8/validation#rule-unique

        $messages = [
            'email.unique' = 'Email taken',
        ];
        
        Validator::make($email, [
            'email' => [
                'required',
                Rule::unique('users')->where(function ($query) use($email) {
                    return $query->where('email', $email);
                }),
            ],
        ],
        $messages
        );
        

        这将帮助您管理所有验证,而不仅仅是一个。如果您添加其他验证,您将向用户返回所有错误,而不仅仅是电子邮件错误。

        【讨论】:

          猜你喜欢
          • 2011-09-18
          • 2021-07-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-23
          • 2014-05-17
          • 2010-10-01
          • 1970-01-01
          相关资源
          最近更新 更多