Laravel 5 Unique form validation ignore id / slug

Hardist picture Hardist · Oct 19, 2015 · Viewed 8.9k times · Source

These are my rules in my class:

class AppointmentsController extends Controller
{
    protected $rules = [
        'appointment' => ['required', 'min:5'],
        'slug'        => ['required', 'unique:appointments'],
        'description' => ['required'],
        'date'        => ['required', 'date_format:"Y-m-d H:i"'],
    ];

This is in the laravel official docs:

Sometimes, you may wish to ignore a given ID during the unique check. For example, consider an "update profile" screen that includes the user's name, e-mail address, and location. Of course, you will want to verify that the e-mail address is unique. However, if the user only changes the name field and not the e-mail field, you do not want a validation error to be thrown because the user is already the owner of the e-mail address. You only want to throw a validation error if the user provides an e-mail address that is already used by a different user. To tell the unique rule to ignore the user's ID, you may pass the ID as the third parameter:

'email' => 'unique:users,email_address,'.$user->id.',user_id'

I tried using this in my rules:

'slug'        => ['required', 'unique:appointments,id,:id'],

This indeed ignores the current row BUT it ignores it completely. What I want to accomplish is, I want it to ignore the current row only if the slug is unchanged. When it is changed to something that is already unique in another row, I want it to throw an error.

Answer

Mina Abadir picture Mina Abadir · Nov 5, 2015

The Unique validator works like that

unique:table,column,except,idColumn

So in your case, you can do it like that:

Get the id you want to validate against, you can get it from the route or with any other way that works for you; something like that

$id = $this->route('id');

'slug'        => ['required','unique:appointments,slug,'.$id],