Laravel update model with unique validation rule for attribute

laravel unique validation on update
laravel validation unique two columns
laravel validation unique except
laravel unique validation with condition
laravel form request validation unique update
laravel ignore unique on update
laravel validation unique column
laravel validation unique email

I have a laravel User model which has a unique validation rule on username and email. In my Repository, when I update the model, I revalidate the fields, so as to not have a problem with required rule validation:

public function update($id, $data) {
    $user = $this->findById($id);
    $user->fill($data);
    $this->validate($user->toArray());
    $user->save();
    return $user;
}

This fails in testing with

ValidationException: {"username":["The username has already been taken."],"email":["The email has already been taken."]}

Is there a way of fixing this elegantly?

Append the id of the instance currently being updated to the validator.

  1. Pass the id of your instance to ignore the unique validator.

  2. In the validator, use a parameter to detect if you are updating or creating the resource.

If updating, force the unique rule to ignore a given id:

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

If creating, proceed as usual:

//rules
'email' => 'unique:users,email_address',

Laravel update model with unique validation rule for attribute, Append the id of the instance currently being updated to the validator. Pass the id of your instance to ignore the unique validator. In the validator, use a  Pass the id of your instance to ignore the unique validator. In the validator, use a parameter to detect if you are updating or creating the resource. If updating, force the unique rule to ignore a given id:

Another elegant way...

In your model, create a static function:

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

Validation on create:

$validator = Validator::make($input, User::rules());

Validation on update:

$validator = Validator::make($input, User::rules($id));

Validation on update, with some additional rules:

$extend_rules = [
    'password'       => 'required|min:6|same:password_again',
    'password_again' => 'required'
];
$validator = Validator::make($input, User::rules($id, $extend_rules));

Nice.

Laravel update model with unique validation rule for attribute , This is a common mistake in Laravel whenever you are updating anything. It will by default require id as a key in order to match the existing entry. So what you need to do is to append the id of the instance currently being updated to the validator. Pass the id of your instance to ignore the unique validator. I have a laravel User model which has a unique validation rule on username and email.In my Repository, when I update the model, I revalidate the fields, so as to not have a problem with required rule validation:

Working within my question:

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

is what I did, based on the accepted answer above.

EDIT: With Form Requests, everything is made simpler:

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

You just need to pass the UpdateUserRequest to your update method, and be sure to POST the model id.

Laravel update model with unique validation rule for attribute, I have a laravel User model which has a unique validation rule on username and email. In my Repository, when I update the model, I revalidate the fields, so as  Sometimes you want to ensure that a field is unique in the database so that someone can’t add the same item twice, such as the title for a post. Laravel provides a couple of handy tools for this, including the Unique validation rule, but there is a bit more configuration required

Unique Validation With Different Column ID In Laravel

'UserEmail'=>"required|email|unique:users,UserEmail,$userID,UserID"

Problem with unique field validation on update, For inserting a new record the validation is working, but when I try to update the record, the http://laravel.com/docs/5.1/validation#rule-unique  Laravel update model with unique validation rule for attribute By Laravel Chef January 21, 2020 March 11, 2020 Problem I have a Laravel User model whre I added unique validation rule on username and email.

Laravel 5 compatible and generic way:

I just had the same problem and solved it in a generic way. If you create an item it uses the default rules, if you update an item it will check your rules for :unique and insert an exclude automatically (if needed).

Create a BaseModel class and let all your models inherit from it:

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

You now define your rules in your model like you are used to:

protected static $rules = [
    'name' => 'required|alpha|unique:roles',
    'displayName' => 'required|alpha_dash',
    'permissions' => 'array',
];

And validate them in your Controller. If the model does not validate, it will automatically redirect back to the form with the corresponding validation errors. If no validation errors occurred it will continue to execute the code after it.

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

That's it! :) Note that on creation we call Role::getRules() and on edit we call $role->getUpdateRules().

Validation on update with unique ID, I am trying to pass the unique attribute of email on update o. it throwing a unique id error or stating that the record already exists. I have tried using the Rule solution in the laravel documentation but I get an error stating Class  For inserting a new record the validation is working, but when I try to update the record, the Laravel gives me the following message: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: ":id" (SQL: select count(*) as aggregate from "products" where "code" = TST0005BYUS and "id" <> :id)

Validation - Laravel, Available Validation Rules; Conditionally Adding Rules; Validating Arrays In this example, if the unique rule on the title attribute fails, the max rule will not be check if the authenticated user actually has the authority to update a given resource. The field under validation must have a valid A or AAAA record according to  Custom Validation Rules. Using Rule Objects. Laravel provides a variety of helpful validation rules; however, you may wish to specify some of your own. One method of registering custom validation rules is using rule objects. To generate a new rule object, you may use the make:rule Artisan command. Let's use this command to generate a rule that verifies a string is uppercase.

Improvements to the Laravel unique and exists validation rules , I have a laravel User model which has a unique validation rule on username and email In my Repository when I update the model I revalida # Validation. Unless you like to live dangerously, any Nova fields that are displayed on the Nova creation / update screens will need some validation. Thankfully, it's a cinch to attach all of the Laravel validation rules you're familiar with to your Nova resource fields.

Updating another user and ignoring its name/email , Validating requests in Laravel is simple with its ValidatesRequests trait that Two rules, exists() and unique(), are used to validate against data stored To get the latest version all you need to do is run composer update and  Now, I can't update the row because it already exist. If I remove the unique validation, I can update the row. But, the row will no longer be unique. I mean I can change the name to anything I want and the update will work. What is your solution for this problem. Thank you :)

Comments
  • So is the User-ID related to the email address or what?
  • Ok. Suppose, if you are updating the email address that already exist, then how to find that?
  • Kindly look this question need help stackoverflow.com/questions/39591620/…
  • @xcy7e 웃: laravel.com/docs/5.3/validation unique:table,column,except,idColumn
  • does it work for only unique, means i have used it in lte as 'order'=> 'lte:products,stock,2' but it's not working why?
  • Very nice! To get mine to work in this manner i needed the following: 'email' => 'required|email|unique:member'. ($id ? ",id,$id" : '')
  • Where do you post the ID?
  • Only this one worked for me. Because in MongoDB primary column is _id, other answers didn't work for me.
  • its for laravel 5.3 version
  • You should format code in answers (I have done that for you). Also, in general an answer should not be only code with no remarks - you may want to add a short explanation of why this particular code is helpful for the situation.
  • Can you explain a bit more?