속성에 대한 고유 한 유효성 검사 규칙이있는 Laravel 업데이트 모델
및 User
에 고유 한 유효성 검사 규칙 이있는 laravel 모델이 있습니다 . 내 저장소에서 모델을 업데이트 할 때 필요한 규칙 유효성 검사에 문제가 없도록 필드를 다시 유효성 검사합니다.username
email
public function update($id, $data) {
$user = $this->findById($id);
$user->fill($data);
$this->validate($user->toArray());
$user->save();
return $user;
}
이것은 테스트에서 실패합니다.
ValidationException: {"username":["The username has already been taken."],"email":["The email has already been taken."]}
이것을 우아하게 고치는 방법이 있습니까?
id
현재 업데이트중인 인스턴스의을 유효성 검사기에 추가합니다 .
패스
id
고유 유효성 검사기를 무시하도록 인스턴스를.유효성 검사기에서 매개 변수를 사용 하여 리소스를 업데이트 하거나 생성 중인지 감지 합니다.
업데이트하는 경우 고유 규칙이 주어진 ID를 무시하도록 강제합니다.
//rules
'email' => 'unique:users,email_address,' . $userId,
생성하는 경우 평소대로 진행하십시오.
//rules
'email' => 'unique:users,email_address',
또 다른 우아한 방법 ...
모델에서 정적 함수를 만듭니다.
public static function rules ($id=0, $merge=[]) {
return array_merge(
[
'username' => 'required|min:3|max:12|unique:users,username' . ($id ? ",$id" : ''),
'email' => 'required|email|unique:member'. ($id ? ",id,$id" : ''),
'firstname' => 'required|min:2',
'lastname' => 'required|min:2',
...
],
$merge);
}
생성시 유효성 검사 :
$validator = Validator::make($input, User::rules());
업데이트 확인 :
$validator = Validator::make($input, User::rules($id));
몇 가지 추가 규칙과 함께 업데이트시 유효성 검사 :
$extend_rules = [
'password' => 'required|min:6|same:password_again',
'password_again' => 'required'
];
$validator = Validator::make($input, User::rules($id, $extend_rules));
좋은.
내 질문 내에서 작업 :
public function update($id, $data) {
$user = $this->findById($id);
$user->fill($data);
$this->validate($user->toArray(), $id);
$user->save();
return $user;
}
public function validate($data, $id=null) {
$rules = User::$rules;
if ($id !== null) {
$rules['username'] .= ",$id";
$rules['email'] .= ",$id";
}
$validation = Validator::make($data, $rules);
if ($validation->fails()) {
throw new ValidationException($validation);
}
return true;
}
위의 대답을 기반으로 한 것입니다.
편집 : 양식 요청을 사용하면 모든 것이 더 간단 해집니다.
<?php namespace App\Http\Requests;
class UpdateUserRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|unique:users,username,'.$this->id,
'email' => 'required|unique:users,email,'.$this->id,
];
}
}
UpdateUserRequest를 업데이트 메서드에 전달하고 모델 ID를 POST해야합니다.
Laravel 5 호환 및 일반적인 방법 :
나는 방금 같은 문제가 있었고 일반적인 방법으로 해결했습니다. 항목을 만들면 기본 규칙을 사용하고 항목을 업데이트하면 규칙을 확인 :unique
하고 자동으로 제외를 삽입합니다 (필요한 경우).
BaseModel
클래스를 만들고 모든 모델 이 클래스를 상속 받도록합니다.
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class BaseModel extends Model {
/**
* The validation rules for this model
*
* @var array
*/
protected static $rules = [];
/**
* Return model validation rules
*
* @return array
*/
public static function getRules() {
return static::$rules;
}
/**
* Return model validation rules for an update
* Add exception to :unique validations where necessary
* That means: enforce unique if a unique field changed.
* But relax unique if a unique field did not change
*
* @return array;
*/
public function getUpdateRules() {
$updateRules = [];
foreach(self::getRules() as $field => $rule) {
$newRule = [];
// Split rule up into parts
$ruleParts = explode('|',$rule);
// Check each part for unique
foreach($ruleParts as $part) {
if(strpos($part,'unique:') === 0) {
// Check if field was unchanged
if ( ! $this->isDirty($field)) {
// Field did not change, make exception for this model
$part = $part . ',' . $field . ',' . $this->getAttribute($field) . ',' . $field;
}
}
// All other go directly back to the newRule Array
$newRule[] = $part;
}
// Add newRule to updateRules
$updateRules[$field] = join('|', $newRule);
}
return $updateRules;
}
}
이제 다음과 같은 방식으로 모델에서 규칙을 정의합니다.
protected static $rules = [
'name' => 'required|alpha|unique:roles',
'displayName' => 'required|alpha_dash',
'permissions' => 'array',
];
그리고 컨트롤러에서 검증하십시오. 모델이 유효성을 검사하지 않으면 해당 유효성 검사 오류가있는 양식으로 자동 리디렉션됩니다. 유효성 검사 오류가 발생하지 않으면 이후에 코드를 계속 실행합니다.
public function postCreate(Request $request)
{
// Validate
$this->validate($request, Role::getRules());
// Validation successful -> create role
Role::create($request->all());
return redirect()->route('admin.role.index');
}
public function postEdit(Request $request, Role $role)
{
// Validate
$this->validate($request, $role->getUpdateRules());
// Validation successful -> update role
$role->update($request->input());
return redirect()->route('admin.role.index');
}
그게 다야! :) 생성시 호출 Role::getRules()
하고 편집시 호출 $role->getUpdateRules()
합니다.
Laravel에서 다른 열 ID로 고유 한 유효성 검사
'UserEmail'=>"required|email|unique:users,UserEmail,$userID,UserID"
BaseModel 클래스가 있으므로 좀 더 일반적인 것이 필요했습니다.
//app/BaseModel.php
public function rules()
{
return $rules = [];
}
public function isValid($id = '')
{
$validation = Validator::make($this->attributes, $this->rules($id));
if($validation->passes()) return true;
$this->errors = $validation->messages();
return false;
}
사용자 클래스에서 유효성을 검사 할 이메일과 이름 만 필요하다고 가정 해 보겠습니다.
//app/User.php
//User extends BaseModel
public function rules($id = '')
{
$rules = [
'name' => 'required|min:3',
'email' => 'required|email|unique:users,email',
'password' => 'required|alpha_num|between:6,12',
'password_confirmation' => 'same:password|required|alpha_num|between:6,12',
];
if(!empty($id))
{
$rules['email'].= ",$id";
unset($rules['password']);
unset($rules['password_confirmation']);
}
return $rules;
}
나는 이것을 phpunit으로 테스트했고 잘 작동합니다.
//tests/models/UserTest.php
public function testUpdateExistingUser()
{
$user = User::find(1);
$result = $user->id;
$this->assertEquals(true, $result);
$user->name = 'test update';
$user->email = 'ddd@test.si';
$user->save();
$this->assertTrue($user->isValid($user->id), 'Expected to pass');
}
더 나은 아이디어를 얻더라도 누군가를 도울 수 있기를 바랍니다. 공유해 주셔서 감사합니다. (라 라벨 5.0에서 테스트 됨)
역할 업데이트에 대한 간단한 예
// model/User.php
class User extends Eloquent
{
public static function rolesUpdate($id)
{
return array(
'username' => 'required|alpha_dash|unique:users,username,' . $id,
'email' => 'required|email|unique:users,email,'. $id,
'password' => 'between:4,11',
);
}
}
.
// controllers/UsersControllers.php
class UsersController extends Controller
{
public function update($id)
{
$user = User::find($id);
$validation = Validator::make($input, User::rolesUpdate($user->id));
if ($validation->passes())
{
$user->update($input);
return Redirect::route('admin.user.show', $id);
}
return Redirect::route('admin.user.edit', $id)->withInput()->withErrors($validation);
}
}
또는 Form Request에서 할 수있는 것은 (Laravel 5.3+의 경우)
public function rules()
{
return [
'email' => 'required|email|unique:users,email,'.$this->user, //here user is users/{user} from resource's route url
];
}
나는 Laravel 5.6에서 해왔고 작동했습니다.
Store 및 Update에 대해 다른 유효성 검사 클래스를 호출하고 있습니다. 제 경우에는 모든 필드를 업데이트하고 싶지 않으므로 만들기 및 편집을위한 공통 필드에 대한 baseRules가 있습니다. 각각에 대해 추가 유효성 검사 클래스를 추가합니다. 제 예가 도움이 되었기를 바랍니다. 저는 Laravel 4를 사용하고 있습니다.
모델:
public static $baseRules = array(
'first_name' => 'required',
'last_name' => 'required',
'description' => 'required',
'description2' => 'required',
'phone' => 'required | numeric',
'video_link' => 'required | url',
'video_title' => 'required | max:87',
'video_description' => 'required',
'sex' => 'in:M,F,B',
'title' => 'required'
);
public static function validate($data)
{
$createRule = static::$baseRules;
$createRule['email'] = 'required | email | unique:musicians';
$createRule['band'] = 'required | unique:musicians';
$createRule['style'] = 'required';
$createRule['instrument'] = 'required';
$createRule['myFile'] = 'required | image';
return Validator::make($data, $createRule);
}
public static function validateUpdate($data, $id)
{
$updateRule = static::$baseRules;
$updateRule['email'] = 'required | email | unique:musicians,email,' . $id;
$updateRule['band'] = 'required | unique:musicians,band,' . $id;
return Validator::make($data, $updateRule);
}
컨트롤러 : 저장 방법 :
public function store()
{
$myInput = Input::all();
$validation = Musician::validate($myInput);
if($validation->fails())
{
$key = "errorMusician";
return Redirect::to('musician/create')
->withErrors($validation, 'musicain')
->withInput();
}
}
업데이트 방법 :
public function update($id)
{
$myInput = Input::all();
$validation = Musician::validateUpdate($myInput, $id);
if($validation->fails())
{
$key = "error";
$message = $validation->messages();
return Redirect::to('musician/' . $id)
->withErrors($validation, 'musicain')
->withInput();
}
}
public static function custom_validation()
{
$rules = array('title' => 'required ','description' => 'required','status' => 'required',);
$messages = array('title.required' => 'The Title must be required','status.required' => 'The Status must be required','description.required' => 'The Description must be required',);
$validation = Validator::make(Input::all(), $rules, $messages);
return $validation;
}
나는 같은 문제가 있었다. 내가 한 일 : 모델의 ID가있는 내보기 숨겨진 필드를 추가하고 유효성 검사기에서보기에서 일부 ID를 얻은 경우에만 고유한지 확인하십시오.
$this->validate(
$request,
[
'index' => implode('|', ['required', $request->input('id') ? '' : 'unique:members']),
'name' => 'required',
'surname' => 'required',
]
);
'email' => [
'required',
Rule::exists('staff')->where(function ($query) {
$query->where('account_id', 1);
}),
],
'email' => [
'required',
Rule::unique('users')->ignore($user->id)->where(function ($query) {
$query->where('account_id', 1);
})
],
다음 코드를 시도해 볼 수 있습니다.
return [
'email' => 'required|email|max:255|unique:users,email,' .$this->get('id'),
'username' => 'required|alpha_dash|max:50|unique:users,username,'.$this->get('id'),
'password' => 'required|min:6',
'confirm-password' => 'required|same:password',
];
외래 키 또는 인덱스로 사용되는 다른 열이있는 경우 이와 같은 규칙에서도이를 지정해야합니다.
'phone' => [
"required",
"phone",
Rule::unique('shops')->ignore($shopId, 'id')->where(function ($query) {
$query->where('user_id', Auth::id());
}),
],
사용자 정의 FormRequest 및 Laravel 5.7+의 경우 다음과 같이 업데이트 된 모델의 ID를 얻을 수 있습니다.
public function rules()
{
return [
'name' => 'required|min:5|max:255|unique:schools,name,'.\Request::instance()->id
];
}
Laravel 5.8 간단하고 쉬운
이 모든 것을 양식 요청으로 아주 멋지게 할 수 있습니다. . .
first make a field by which you can pass the id (invisible) in the normal edit form. i.e.,
<div class="form-group d-none">
<input class="form-control" name="id" type="text" value="{{ $example->id }}" >
</div>
... Then be sure to add the Rule class to your form request like so:
use Illuminate\Validation\Rule;
... Add the Unique rule ignoring the current id like so:
public function rules()
{
return [
'example_field_1' => ['required', Rule::unique('example_table')->ignore($this->id)],
'example_field_2' => 'required',
];
... Finally type hint the form request in the update method the same as you would the store method, like so:
public function update(ExampleValidation $request, Examle $example)
{
$example->example_field_1 = $request->example_field_1;
...
$example->save();
$message = "The aircraft was successully updated";
return back()->with('status', $message);
}
This way you won't repeat code unnecessarily :-)
public function rules()
{
if ($this->method() == 'PUT') {
$post_id = $this->segment(3);
$rules = [
'post_title' => 'required|unique:posts,post_title,' . $post_id
];
} else {
$rules = [
'post_title' => 'required|unique:posts,post_title'
];
}
return $rules;
}
'IT TIP' 카테고리의 다른 글
jQuery에서 사용자 정의 함수 호출 (0) | 2020.12.14 |
---|---|
CSS에서 6 자리 색상 코드 대신 3 자리 색상 코드를 사용하는 방법은 무엇입니까? (0) | 2020.12.14 |
지금부터 5 초 후 Java로 어떻게 말합니까? (0) | 2020.12.13 |
Python에서 JSON 출력 정렬 (0) | 2020.12.13 |
Rails ActiveRecord 모델을 읽기 전용으로 만드는 쉬운 방법이 있습니까? (0) | 2020.12.13 |