11

I create laravel form validation request and have unique rules on that validation.

I want use it on store and update method without create new form request validation again.

but the problem is when on store the id doesnt exist and the validate is passed and when on update i failed the pass the validating because the id is exist on storage

i want to ignore the id on unique rules but use same form validate request

what is best practice to check on form validate request class if this action from store or update method to ignore unique id ?

7 Answers7

15

Ok.. i can do it like @porloscerros Ψ suggest

    public function rules()
    {
        $rules = [
            'name' => 'required|string|unique:products|max:255',
        ];

        if (in_array($this->method(), ['PUT', 'PATCH'])) {
            $product = $this->route()->parameter('product');

            $rules['name'] = [
                'required',
                'string',
                'max:255',
                Rule::unique('loan_products')->ignore($product),
            ];
        }

        return $rules;
    }
  • Working like charm!!! – Gautam Patadiya Dec 30 '21 at 12:01
  • I posted a much cleaner version below. No need for the conditional. If `$this->route()->parameter('product')` returns null, `Rule::unique('loan_products')->ignore($product)`, will ignore `ignore()`, so it all can be done in one statement. See my post. – mangonights May 23 '23 at 20:15
2

Try this, it worked for me.

Laravel unique: third param can exclude the id for example, of the record, like this:

public function rules()
{
  return [
     'name' => 'required|string|max:255|unique:products,'.$this->id,      
  ];
}
BaoO
  • 21
  • 3
1
public function rules()
{
    if (request()->isMethod('post')) {
        $rules = [
            'image' => 'required|image|mimes:jpeg,jpg,png|max:2000',
            'name' => 'required|unique:categories'
        ];
    } elseif (request()->isMethod('PUT')) {
        $rules = [
            'name' => 'required|unique:categories,name'
        ];
    }
    return $rules;
}
0

im using this

$validated = $request->validated();

use this method:

public function createAccount(RegisterRequest $request)
{
    $attr = $request->validated();

instead of something like this:

public function createAccount(Request $request)
{
    $attr = $request->validate([
        'name' => 'required|string|max:255',
        'email' => 'required|string|email|unique:users,email',
        'password' => 'required|string|min:6|confirmed'
    ]);

use php artisan make:request RegisterRequest

public function rules()
{
    return [
        'name' => 'required|string|max:255',
        'email' => 'required|string|email|unique:users,email',
        'password' => 'required|string|min:6|confirmed'
    ];
}
saber tabatabaee yazdi
  • 4,404
  • 3
  • 42
  • 58
0

I recently started doing this. I will name the FormRequest using 'Upsert', so example UpsertStudentRequest. And the uniqueness rule can be simplified down to the following. If there is no parameter, it returns null and ignore() is just ignored and only Rule::unique('students') is enforced.

// UpsertStudentRequest

public function rules()
{
    return [
        'foo' => [
            'required',
            'string',
            Rule::unique('students')->ignore($this->route()->parameter('student')),
        ],
    ];
}

mangonights
  • 909
  • 1
  • 10
  • 11
0

because i'm using file upload in update i cant use put so both route are POST that why i use route name

    $id= $this->route('product'); 
    $rules= [
        'name' => 'required',
        'sku' =>'required|unique:products,sku,' .$id,
        'image' => 'nullable|image|max:1024', // Max 1MB
    ];
    if(Route::currentRouteName() == "products.store"){
        $rules['sku'] = 'required|unique:products';
    };
  
    return $rules;
aitbella
  • 958
  • 9
  • 19
-1

Why are you checking the id when store or update in FormRequest? You don't need this. The id comes to your controller's method like as parameter. Or laravel will create the model using DI in the your controller's method public function update(User $user) and then you can use $user like an instance of User model. You may check the id in web.php or api.php: https://laravel.com/docs/7.x/routing#parameters-regular-expression-constraints

And I suggest you not to use one FormRequest for two methods. This is bad practice

  • Because my rules for `store` and `update` almost same except on `name` id The name cannot duplicate and when create new product with name `product 1` if not exists on storage i can store it.. but when i want edit the validation failed because duplicate `name` on storage so i need to ignore the product id on storage to pass the validation. So if i make one form request validation it will easy to maintainable. – Panji Setya Nur Prawira May 01 '20 at 13:59
  • ok. You need to make new unique rule for validation this field. Here documentation: https://laravel.com/docs/7.x/validation#rule-unique – Denis Emelianenko May 03 '20 at 09:28