Making unique field validation while updating - php

I am trying to validate for the unique record While editing but it always displays the field must be unique. basically i need to ignore the value of that id. id is the primary key.
$validator=Validator::make($request->all(),[
'name'=>'required',
'telephone'=>'required|unique:telephone',
'email'=>'unique:telephone',
'altemail'=>'unique:telephone',
'image'=>'image',
]);
if($validator->fails()){
return redirect('/telephone/addview')
->withErrors($validator);
}

use additional arguments for unique rule
$validator=Validator::make($request->all(),[
'name'=>'required',
'telephone'=>'required|unique:telephone,telephone,'.$yourMdelInstance->id,
'email'=>'unique:telephone,email,'.$yourMdelInstance->id,
'altemail'=>'unique:telephone,altemail,'.$yourMdelInstance->id,
'image'=>'image',
]);

You can see in the docs you can exclude a value in your unique validation.
Example:
// YourController.php
publiuc function postUpdate(Request $request)
{
// Get your resource first.
$model = Model::find($request->input('id'));
// Check if exists
if (!$model) \App::abort(404);
// Validate
$this->validate($request, [
'...'
'telephone' => 'required|unique:yourtablename,telephone,'.$model->telephone,
'...'
]);
}

Related

Laravel Validation Request, how to handle validation on update?

First of all I love the way that validation is going through, can now easily use
public function authorize(Authenticator $auth)
{
return $auth->user()->hasRole('administrator');
}
hat's not the problem, I bump always into another problem... that is when you update an record, how to do things with the rules? If I need to update an email, I need the following string: 'email' => 'unique:users,email_address,10'. In this case it should look like:
public function rules()
{
return [
'email' => 'required|unique:users,id,?????',
'tags' => 'required'
];
}
It's more simple.
The Laravel documentation says "If your table uses a primary key column name other than id, you may specify it as the fourth parameter":
'email' => 'unique:users,email_address,'.$user->id.',user_id'
If for example, you want to verify if a username exists, but excluding current user ID:
// UpdateUserRequest.php
public function rules() {
//
return [
'username' => 'required|unique:users,username,' . $this->id . ',id',
];
}

Laravel unique ruleset ignores the current user id

I'm working on updating a user in Laravel, where I made the following validation rule for updating a users email:
"email" => "required|email|unique:users,email,".$this->route("user")->id,
This is inside of my form request.
However, when I post, it still says that the email is already taken? Is this perhaps a bug in the latest version of Laravel?
Thanks!
No it is not a bug, you are using a null value for the id hence the reason why, change your rule to this:
"email" => "required|email|unique:users,email,".$this->user()->id,
Make sure that you have Request $request in your method, and also you have the auth middleware on your controller.
you set the ignore email column so you should pass email not id
"email" => "required|email|unique:users,email,".$this->route("user")->email,
First you have to add rules in user model
static function rules() {
return [
'email' => 'required|email'
];
}
In user controller
use Illuminate\Validation\Rule; // add this one
function add_update_user(Request $request,$user_id) {
$data = $request->all();
unset($data['_token']);
$rules = User::rules();
$rules['email'] = explode('|', $rules['email']);
if (isset($user_id)) // is old user, your get user_id in route
{
$rules['unique_code'][] = Rule::unique('databse_connection_name.users')->ignore($data['email'], 'email');
} else // is new user
{
$rules['email'][] = 'unique:databse_connection_name.users,email';
}
$validator = Validator::make($data, $rules);
...
...
}

rules() function in Laravel Request doesn't create unique slugs

I'm trying to make simple unique slugs. The slugs are saved correctly in database, so the function is working. I have problems with making them unique.
I have this rule in TagCreateRequest.php
public function rules()
{
$rules = [
'tag' => 'required|min:3',
'tag_slug' => 'required|alpha_dash|unique:tag,tag_slug,'
];
$rule = 'unique:tag';
$segments = $this->segments();
$id = intval(end($segments));
if ($id != 0) {
$rule .= ',tag_slug,' . $id;
}
$rules['tag_slug'][] = $rule;
return $rules;
}
and this in my store function in the controller
public function store(TagCreateRequest $request)
{
$tag = new Tag();
foreach (array_keys($this->fields) as $field) {
$tag->$field = $request->get($field);
}
$tag->save();
return redirect()->route('tags');
}
The error is about trying to add duplicate value
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'unique slug' for key 'tags_tag_unique'
Can someone help me to fix this issue?
You can access the id field magically. ID must be the same route parameter used in your route.
If you use id parameter like as Route::put('post/{id}/update') then you can magically access the id parameter inside your form request. Otherwise, if you call the parameter of {post} Route::put('post/{post}/update'), in your form request you must be call $this->post instead of $this->id, ok?
Please try it:
public function rules()
{
$rules = [
'tag' => 'required|min:3'
];
$slugRule = 'required|alpha_dash|unique:tag_slug';
if (! empty($this->id)) {
$slugRule = 'required|alpha_dash|unique:tag_slug,'.$this->id;
}
$rules['tag_slug'] = $slugRule;
return $rules;
}
This FormRequest will work fine on the store() and update() methods if you inject him in both methods.
See it:
// Your store route
Route::post('/post/store', ['as' => 'post.store', 'uses' => 'YourController#store']);
// YourController store method
public function store(NameSpaced\FormRequest $request)
{
// ...
}
// Your update route
Route::post('/post/{id}/update', ['as' => 'post.update', 'uses' => 'YourController#store']);
// YourController update method
public function update(NameSpaced\FormRequest $request)
{
// ...
}
$rules = [
'tag' => 'required|min:3',
'tag_slug' => 'required|alpha_dash|unique:[table name],[column name]'
];
Try this the first is table name and the second is column name that you wanted to unique, write without adding square braces. or you just pass table name like this,
$rules = [
'tag' => 'required|min:3',
'tag_slug' => 'required|alpha_dash|unique:[table name]'
];
laravel auto checks for the column.
I hope it helps.
I would suggest that you automatically generate a new slug whenever you are creating a tag. I got myself in same issues that you have listed here, so i decided on automatically generating whenever i am creating a new item. I used laravel-sluggable. It automatically generates unique slugs.
As per your question, i have defined a unique slug rule in one of my demo apps like this:
public function rules()
{
return [
'name' => 'required|string|max:255',
'slug' => 'required|string|max:255|unique:categories,slug,'.$this->segment(3),
];
}
Please note that $this->segment(3) refers to the id of the model being updated in the backend pages, it can be different in your application.

L5.3 - Validator - Get DB record when 'unique' si triggered

I'm using Validator to validate the input:
$validator = Validator::make($request->all(), [
'short' => 'required',
'name' => 'required|unique:type_event,name'
]);
if ($validator->fails()) {
// fails validation
}
When the unique check is fired, is there a way to receive the id or the record that already exists into the DB? Or I've to call the Model for example with:
$data = TypeEventModel::where('name', '=', $request->input('name'))->firstOrFail();
Thank you.
First you need a custom validation rule. Add the following code to app/Providers/AppServiceProvider.php in boot() method:
Validator::extend('unique_with_id', function ($attribute, $value, $parameters, $validator) {
// First we query for an entity in given table, where given field equals the request value
$found = DB::table($parameters[0])
->where($parameters[1], $value)
->first();
// then we add custom replacer so that it gives the user a verbose error
$validator->addReplacer('unique_with_id', function ($message, $attribute, $rule, $parameters) use ($found) {
// replace :entity placeholder with singularized table name and :id with duplicate entity's id
return str_replace([':entity', ':id'], [str_singular($parameters[0]), $found->id], $message);
});
// finally return wether the entity was not found (the value IS unique)
return !$found;
});
Then add the following validation message to resources/lang/en/validation.php
'unique_with_id'=>'Same :entity exists with ID :id',
Finally you can use
$validator = Validator::make($request->all(), [
'short' => 'required',
'name' => 'required|unique_with_id:type_event,name'
]);

Laravel validation unique with where closure

I have a table called taxonomy. It's columns are id, name, slug, type (tag, category). I have created a separate controller for tag and category.
Now I need to apply a unique validation rule on slug:
where type = tag
Unique rule with the additional where clause
'slug' => Rule::unique('taxonomy')->where(function ($query) {
return $query->where('type', 'tag');
})
You can apply unique rule like this for insert and update both in single validation function.
public function validateTaxonomy(Request $request){
if(isset($request->id) && $request->id){
$id = ','.$request->id.',id,type,'.$request->tag;
}else{
$id = ',Null,id,type,'.$request->tag;
}
$rules = [
'slug' => 'required|unique:taxonomy,slug'.$id,
];
return Validator::make($request->all(), $rules);
}
Example to call from store function
public function store(Request $request)
{
$validator = $this->validateTaxonomy($request);
if($validator->fails()){
return redirect()->back()->withErrors($validator)->withInput();
}
...
}
Try this:
'postData' => 'unique:table_name,column_name'
see more validation here:
Validation Laravel
Unique rule with the additional where clause
'slug' => Rule::unique('taxonomy')->where('type', 'tag')

Categories