source

Larabel: 업데이트 시 고유 검증

manycodes 2022. 11. 25. 20:55
반응형

Larabel: 업데이트 시 고유 검증

이전에도 여러 번 물어본 질문이지만 모델에서 인증할 때 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"
];

모델/베이스 모델

    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;
}

이 의 답은 '아까운 이야기'입니다.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,
  ]);
}

업데이트: 로그인한 사용자를 갱신하고 있으며, 이 사용자를 삽입하지 않은 경우User 시 되지 않은 할 수 있습니다.id$this->user 다음과 같이

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

Larabel 5.7 이후 보다 우아한 방법은 다음과 같습니다.

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

추신: 신입사원들에게 이 예를 명확히 하기 위해 필수 및 이메일과 같은 몇 가지 규칙을 추가했습니다.

하나의 심플한 솔루션.

고객님의 모델

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

컨트롤러에서 액션: update

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

이것을 하는 우아한 방법이 있다.리소스 컨트롤러를 사용하는 경우 레코드를 편집하는 링크는 다음과 같습니다.

/users/{user}/편집 OR /users/1/편집

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를 무시하도록 고유 규칙 강제 적용:

네가 원하는 걸 내가 이해한다면:

'email' => 'required|email|mail:users, email_address', $id.'

모델 업데이트 방법에서는 예를 들어 파라미터가 포함된 $id를 받아야 합니다.

영어가 서툴러서 죄송합니다.

최적의 옵션은 데이터 업데이트에 대한 고유한 검증 시 코드를 추가하지 않고 한 번만 사용해 보십시오.

'email' => 'unique:users,email_address,' . $userId,

여기서email필드명과 users 테이블명과 email_address 원하는 테이블 속성 이름입니다. $userid 행 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;
    }    
}

버전 5.2에서 테스트된 보다 심플한 솔루션

당신의 모델에서는

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

해결책은 다음과 같습니다.

업데이트의 경우:

public function controllerName(Request $request, $id)

{

    $this->validate($request, [
        "form_field_name" => 'required|unique:db_table_name,db_table_column_name,'.$id
    ]);

    // the rest code
}

바로 그겁니다.해피 코딩 :)

아래 코드 테스트:

'email' => 'required|email|unique:users,email_address,'. $id .'ID'

여기서 ID는 테이블의 프라이머리 ID입니다.

이거 드셔보세요.

protected $rules_update = [
    'email_address' => 'required|email|unique:users,email_address,'. $this->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"
];

이것을 하는 간단하고 우아한 방법이 있다.user_id를 본문 요청으로 전달하거나 쿼리 파라미터를 통해 전달하는 경우.

/update/profile?user_id=

그러면 요청 규칙에서

  public function rules(Request $request)
    {
        return [
            'first_name' => 'required|string',
            'last_name' => 'required|string',
            'email' => ['required','email', 'string', Rule::unique('users')->ignore($request->user_id )],
            'phone_number' => ['required', 'string', Rule::unique('users')->ignore($request->user_id )],
        ];
    }

좋은 방법) 더 방법, 더 좋은 방법, 더 좋은 방법, 더 좋은 방법auth->id()$request->user_id아이디

별도의 규칙 방법이 있는 경우.다음과 같은 구문을 쉽게 사용할 수 있습니다.

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

- 아, 아, 아! - 아, 아, 아!Laravel 8.x 하면 .Rule::unique 및 방법

특정 ID를 무시하도록 고유 규칙 강제 적용:

use Illuminate\Validation\Rule;

public function update(Request $request, Post $post)
{
    $validatedData = $request->validate([
        'name' => ['required', 'max:60', Rule::unique('posts')->ignore($post->id)],
    ]);

    $post->update($validatedData);
    
    return redirect(route('posts.index'))->with('status', 'post updated successfully');
}

컨트롤러에서 한 단계 실행

Larabel 9로 동작 가능

$request->validate([
        'name'=>'required|unique:categories,name,'.$id,
    ]);

나는 이런 식으로 그것을 해결할 것이다.

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

요청에서 ID를 가져와 규칙에 전달합니다.

$rules = [
    "email" => "email|unique:users, email, '.$id.', user_id"
];

Illuminate\Validation\규칙\고유;

고유한 유효성 검사를 통해 문자열 유효성 검사를 규칙 개체에 구문 분석합니다.

고유한 검증 패턴: %s, %s, %s, %s, %s'

대응 대상: 테이블 이름, 열, 무시, id 열, 형식 지정 위치

/**
 * 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()
    ), ',');
}

가장 쉬운 방법을 찾아 Larabel 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;
}

Larabel 6.0에 사용

use Illuminate\Validation\Rule;

public function update(Request $request, $id)
    {
        // Form validation
        $request->validate([
            'category_name'   =>  [
                'required',
                'max:255',
                 Rule::unique('categories')->ignore($id),
            ]
        ]);
}

테이블 이름을 하드 코딩하지 않으려면 모델 클래스 경로를 사용할 수도 있습니다.

function rules(){
    return [
        'email' => ['required','string',
         Rule::unique(User::class,'email')->ignore($this->id)]
    ];
}

여기서 $this->id는 0 또는 갱신되는 레코드 ID 중 하나입니다.

독특한 칼럼을 포함한 이 방대한 검증 토픽에 대해 많은 조사를 한 결과, 최적의 어프로치를 얻을 수 있었습니다.봐주세요

컨트롤러 내

    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Validator;

    class UserController extends Controller
    {
         public function saveUser(Request $request){
                $validator = Validator::make($request->all(),User::rules($request->get('id')),User::$messages);
                if($validator->fails()){
                    return redirect()->back()->withErrors($validator)->withInput();
                }
            }
    }

saveUser메서드를 호출하여 사용자 레코드를 추가/업데이트할 수 있습니다.

인유 모델

class User extends Model
{
    public static function rules($id = null)
    {
        return [
            '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"
        ];
    }
    public static $messages = [
        'email_address.required' => 'Please enter email!',
        'email_address.email' => 'Invalid email!',
        'email_address.unique' => 'Email already exist!',
        ...
    ];
}

이게 내가 결국 하게 된 일이야.좀 더 효율적인 방법이 있을 거라고 확신하지만 이게 내가 생각해낸 거야.

Model/User.php

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

모델/베이스 모델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를 전달합니다.

컨트롤러/사용자 컨트롤러php

public function update($id) { 

   .....

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

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

    ....


}

기존 데이터 쓰기 검증 프로그램을 다음과 같이 업데이트할 때:

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

특정 열에 대한 기존 사용자 ID의 고유 값 일치를 건너뛰거나 무시합니다.

아래 코드 테스트:

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

아주 쉽게 할 수 있습니다.

컨트롤러에 기입

$this->validate($request,[
     'email'=>['required',Rule::unique('yourTableName')->ignore($request->id)]
]);
Note : Rule::unique('yourTableName')->ignore($idParameter) , here $idParameter you can receive from get url also you can get it from hidden field.
Most important is don't forget to import Rule at the top.

로그인 사용자가 이메일을 갱신할 경우 auth() 도우미 함수는 로그인 사용자 ID auth()->user()->ID를 제공합니다.

Laravel helpers #method-auth

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

]);

관리자가 사용자 목록에서 특정 사용자 정보를 변경할 경우 다음과 같이 검증됩니다.

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

Laravel 검증 #규칙 고유

$request 객체에는 현재 루트 관련 모델개체가 포함되어 있습니다.그럼 모델이 되는 거죠

Try dd($request)

솔루션:

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

그 후 유효성 검사:

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

논리적으로 폼의 전자 메일 주소가 다르면 검증해야 하고, 전자 메일이 변경되지 않았다면 검증할 필요가 없으므로 검증에서 해당 규칙을 삭제해야 합니다.

위해서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));

이렇게 하면 저장 및 업데이트 방식에 대해 두 개의 서로 다른 규칙 집합을 정의할 필요가 없습니다.

가독성을 조금 양보할 수 있는 경우,

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]
    ];
}

나는 이전 글을 읽었지만, 아무도 진짜 문제에 접근하지 않았다.add 및 edit case에 적용하기 위해서는 고유한 규칙을 사용해야 합니다.저는 이 규칙을 케이스 편집 및 추가에 사용하고 있으며 정상적으로 작동합니다.

솔루션에서는 Request Class의 규칙 함수를 사용합니다.

  1. 편집 양식의 숨겨진 입력 양식 필드에 ID를 보냈습니다.
  2. 규칙 함수에서는 원하는 열로 검색하여 레코드를 가져옵니다.
  3. 이제 상황을 평가해보세요.기존 레코드와 ID가 같을 경우 일의는 활성화되지 않아야 합니다(즉, 평균 편집 레코드).

코드에 대해서:

public function rules()
    {
        //
        $user = User::where('email', $this->email)->first();
        //
        $this->id = isset($this->id) ? $this->id : null;
        $emailRule = (($user != null) && ($user->id == $this->id)) ? 'required|email:rfc,dns|max:255' : 'required|unique:users|email:rfc,dns|max:255';
        //        
        return [
            //
            'email'            =>  $emailRule,                
            //
        ];
        //


    }

업데이트를 수행할 때 업데이트 중인 레코드를 무시하고 싶기 때문에ignore다른 사람들도 언급했듯이하지만 저는 그 예시를 받는 것을 선호합니다.User그냥 신분증이라기 보다는요.이 방법을 사용하면 다른 모델에 대해서도 동일한 작업을 수행할 수 있습니다.

컨트롤러

    public function update(UserRequest $request, User $user)
    {
        $user->update($request->all());

        return back();
    }

사용자 요구

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

업데이트: 사용ignoreModel대신해서ignore

언급URL : https://stackoverflow.com/questions/23587833/laravel-validation-unique-on-update

반응형