web-dev-qa-db-ja.com

Laravel:更新時に一意の検証

この質問はこれまで何度も尋ねられてきましたが、モデルで検証しているときにidを取得する方法を説明する人はいません。

'email' => 'unique:users,email_address,10'

検証ルールはモデル内にあるため、レコードのIDを検証ルールに渡す方法を教えてください。

こちらが私のモデル/ユーザーです

protected $rules_update = [
    'email_address' => 'required|email|unique:users,email_address,'.$id,
    'first_name' => "required",
    'last_name' => "required",
    'password' => "required|min:6|same:password_confirm",
    'password_confirm' => "required:min:6|same:password",
    'password_current' => "required:min:6"
];

モデル/ BaseModel

    protected $rules = array();

public $errors;

/*
    * @data: array, Data to be validated
    * @rules: string, rule name in model 
*/

public function validate($data, $rules = "rules") {

    $validation  = Validator::make($data, $this->$rules);

    if($validation->passes()) {
        return true;
    }

    $this->errors = $validation->messages();

    return false;
}
33
user742736

1つの簡単なソリューション。

あなたのモデルで

protected $rules = [
    'email_address' => 'sometimes|required|email|unique:users',
    ..
];

コントローラーで、action:update

...
$rules = User::$rules;
$rules['email_address'] = $rules['email_address'] . ',id,' . $id;
$validationCertificate  = Validator::make($input, $rules); 
27
Ricardo Canelas

ちなみに、この質問に対するほとんどの回答はemail_addressについて語っていますが、Laravelの組み込み認証システムでは、メールフィールド名はemailです。一意のフィールド、つまり更新に関する電子メールを検証する方法の例を次に示します。

Form Request では、次のようにします。

public function rules()
{
  return [
      'email' => 'required|email|unique:users,email,'.$this->user->id,
  ];
}

または、コントローラー内のデータを直接検証する場合:

public function update(Request $request, User $user)
{
  $request->validate([
      'email' => 'required|email|unique:users,email,'.$user->id,
  ]);
}

Update:サインインしているユーザーを更新していて、Userモデルをルートに挿入していない場合、未定義のプロパティが発生する可能性があります$this->useridにアクセスするとき。その場合は、次を使用します。

public function rules()
    {
      return [
          'email' => 'required|email|unique:users,email,'.$this->user()->id,
      ];
    }

Laravel 5.7以降のよりエレガントな方法は:

public function rules()
{
    return [
        'email' => ['required', 'email', \Illuminate\Validation\Rule::unique('users')->ignore($this->user()->id)]
    ];
}

追伸:初心者向けにこの例を明確にするために、他のいくつかのルール、つまり必須とメールを追加しました。

22
Rehmat

これを行うエレガントな方法があります。リソースコントローラーを使用している場合、レコードを編集するためのリンクは次のようになります。

/ users/{user}/edit [〜#〜] or [〜#〜]/users/1/edit

そして、あなたのUserRequestでは、ルールは次のようになります:

public function rules()
{
    return [
        'name' => [
            'required',
            'unique:users,name,' . $this->user
        ],
    ];
}

または、レコードを編集するためのリンクが次のようになっている場合:

/ users/edit/1

これも試すことができます:

public function rules()
{
    return [
        'name' => [
            'required',
            'unique:users,name,' . $this->id
        ],
    ];
}
17
Him Hah

Laravel 5.7から、これはうまく機能します

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);

一意のルールに特定のIDを無視させる:

6
tewshi

私があなたが望むものを理解している場合:

「メール」=>「必須|メール|一意:ユーザー、メールアドレス」。 $ id ''

モデル更新メソッドでは、例として、パラメーター付きの$ idを受け取る必要があります。

すみません、英語が下手です。

6
Lucas
public function rules()
{

    switch($this->method())
    {
        case 'GET':
        case 'DELETE':
        {
            return [];
        }
        case 'POST':
        {
            return [
                'name' => 'required|unique:permissions|max:255',
                'display_name' => 'required',
            ];
        }
        case 'PUT':
        case 'PATCH':
        {
            return [                    
                'name' => 'unique:permissions,name,'.$this->get('id').'|max:255',
                'display_name' => 'required',
            ];
        }
        default:break;
    }    
}
3
Janak Bhatta
$rules = [
    "email" => "email|unique:users, email, '.$id.', user_id"
];

Illuminate\Validation\Rules\Unique;

一意の検証は、文字列検証をルールオブジェクトに解析します

一意の検証のパターンは次のとおりです。一意:%s、%s、%s、%s、%s '

対応:テーブル名、列、無視、ID列、フォーマットwheres

/**
 * Convert the rule to a validation string.
 *
 * @return string
 */
public function __toString()
{
    return rtrim(sprintf('unique:%s,%s,%s,%s,%s',
        $this->table,
        $this->column,
        $this->ignore ?: 'NULL',
        $this->idColumn,
        $this->formatWheres()
    ), ',');
}
3
thenguyenit

バージョン5.2でテストされたさらにシンプルなソリューション

あなたのモデルで

// validator rules
public static $rules = array(
    ...
    'email_address' => 'email|required|unique:users,id'
);
3
Altravista

私はこのようなことをすることでそれを解決します

public function rules()
{
    return [
         'name' => 
            'required|min:2|max:255|unique:courses,name,'.\Request::get('id'),
    ];
}

リクエストからIDを取得してルールに渡す場所

2
Matovu Ronald

Laravel 5.2

public function rules()

{

switch ($this->method()) {
    case 'PUT':
        $rules = [
            'name'                  => 'required|min:3',
            'gender'                => 'required',
            'email'                 => 'required|email|unique:users,id,:id',
            'password'              => 'required|min:5',
            'password_confirmation' => 'required|min:5|same:password',
        ];
        break;

    default:
        $rules = [
            'name'                  => 'required|min:3',
            'gender'                => 'required',
            'email'                 => 'required|email|unique:users',
            'password'              => 'required|min:5',
            'password_confirmation' => 'required|min:5|same:password',
        ];
        break;
}

return $rules;
}
2
zarpio

既存のデータ書き込みバリデータを次のように更新している間:

'email' => ['required','email', Rule::unique('users')->ignore($user->id)]

これは、特定の列に一致する既存のユーザーのIDの一意の値をスキップ/無視します。

0
Saiful Islam

私の解決策:

$rules = $user->isDirty('email') ? \User::$rules : array_except(\User::$rules, 'email');

次に検証で:

$validator = \Validator::make(\Input::all(), $rules, \User::$messages);

ロジックは、フォーム内の電子メールアドレスが異なる場合は検証する必要があり、電子メールが変更されていない場合は検証する必要がないため、検証からそのルールを削除します。

0
Silver Paladin

$ validator = Validator :: make(array( 'E-mail' => $ request ['email']、)、array( 'E-mail' => 'required | email | unique:users、email、'。$ request ['id']、));

0

「メール」=>「必須|メール|一意:ユーザー、メールアドレス」。 $ id .'ID '

IDはテーブルのプライマリIDです

0
Sonam Tomar

コントローラーのuniqueルールの場合-storeメソッドとupdateメソッドでは明らかに異なりますが、通常はrulesのコントローラー内に関数を作成します。ルールの配列。

protected function rules($request)
{
    $commonRules = [
        'first_name' => "required",
        'last_name' => "required",
        'password' => "required|min:6|same:password_confirm",
        'password_confirm' => "required:min:6|same:password",
        'password_current' => "required:min:6"
    ];

    $uniqueRules = $request->id

          //update
        ? ['email_address' => ['required', 'email', 'unique:users,email' . $request->get('id')]]

          //store
        : ['email_address' => ['required', 'email', 'unique:users,email']];


    return array_merge($commonRules, $uinqueRules);
}

次に、それぞれのstoreおよびupdateメソッドで

$validatedData = $request->validate($this->rules($request));

これにより、ストアメソッドと更新メソッドの2つの異なるルールセットを定義する必要がなくなります。

読みやすさについて少し妥協する余裕がある場合は、

protected function rules($request)
{
    return [
        'first_name' => "required",
        'last_name' => "required",
        'password' => "required|min:6|same:password_confirm",
        'password_confirm' => "required:min:6|same:password",
        'password_current' => "required:min:6",
        'email_address' => ['required', 'email', 'unique:users,email' . $request->id ?: null]
    ];
}

0
Donkarnash

これが私がやったことです。これを行うより効率的な方法があると確信していますが、これが私が思いついたものです。

Model/User.php

protected $rules = [
    'email_address' => 'sometimes|required|email|unique:users,email_address, {{$id}}',
];

Model/BaseModel.php

public function validate($data, $id = null) {


      $rules = $this->$rules_string;

     //let's loop through and explode the validation rules
     foreach($rules as $keys => $value) {

        $validations = explode('|', $value);

        foreach($validations as $key=>$value) {

            // Seearch for {{$id}} and replace it with $id
            $validations[$key] = str_replace('{{$id}}', $id, $value);

        }
        //Let's create the pipe seperator 
        $implode = implode("|", $validations);
        $rules[$keys] = $implode;

     }
     ....

  }

コントローラの検証に$ user_idを渡します

Controller/UserController.php

public function update($id) { 

   .....

    $user = User::find($user_id);

    if($user->validate($formRequest, $user_id)) {
      //validation succcess 
    } 

    ....


}
0
user742736