この質問はこれまで何度も尋ねられてきましたが、モデルで検証しているときに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;
}
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);
ちなみに、この質問に対するほとんどの回答は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->user
でid
にアクセスするとき。その場合は、次を使用します。
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)]
];
}
追伸:初心者向けにこの例を明確にするために、他のいくつかのルール、つまり必須とメールを追加しました。
これを行うエレガントな方法があります。リソースコントローラーを使用している場合、レコードを編集するためのリンクは次のようになります。
/ 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
],
];
}
Laravel 5.7から、これはうまく機能します
use Illuminate\Validation\Rule;
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);
私があなたが望むものを理解している場合:
「メール」=>「必須|メール|一意:ユーザー、メールアドレス」。 $ id ''
モデル更新メソッドでは、例として、パラメーター付きの$ idを受け取る必要があります。
すみません、英語が下手です。
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;
}
}
$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()
), ',');
}
バージョン5.2でテストされたさらにシンプルなソリューション
あなたのモデルで
// validator rules
public static $rules = array(
...
'email_address' => 'email|required|unique:users,id'
);
私はこのようなことをすることでそれを解決します
public function rules()
{
return [
'name' =>
'required|min:2|max:255|unique:courses,name,'.\Request::get('id'),
];
}
リクエストからIDを取得してルールに渡す場所
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;
}
既存のデータ書き込みバリデータを次のように更新している間:
'email' => ['required','email', Rule::unique('users')->ignore($user->id)]
これは、特定の列に一致する既存のユーザーのIDの一意の値をスキップ/無視します。
私の解決策:
$rules = $user->isDirty('email') ? \User::$rules : array_except(\User::$rules, 'email');
次に検証で:
$validator = \Validator::make(\Input::all(), $rules, \User::$messages);
ロジックは、フォーム内の電子メールアドレスが異なる場合は検証する必要があり、電子メールが変更されていない場合は検証する必要がないため、検証からそのルールを削除します。
$ validator = Validator :: make(array( 'E-mail' => $ request ['email']、)、array( 'E-mail' => 'required | email | unique:users、email、'。$ request ['id']、));
「メール」=>「必須|メール|一意:ユーザー、メールアドレス」。 $ id .'ID '
IDはテーブルのプライマリIDです
コントローラーの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]
];
}
これが私がやったことです。これを行うより効率的な方法があると確信していますが、これが私が思いついたものです。
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
}
....
}