Delvin
Delvin

Reputation: 11

dont want to edit particular field which is used in store and update functions

ProductController

public function store()
{
    $product = Product::create($this->validateRequest());

    return redirect('/product');
}

public function update(Product $product)
{
    $product->update($this->validateRequest());

    return redirect('/product');
}

private function validateRequest()
{
    return request()->validate([

        'sub_category_id' => ['required'],

        'name' => ['required', 'min:4'],

        'code' => ['required', 'alpha_dash','unique:products'],

        'description' => ['required', 'min:4'],

        'color' => ['required', 'min:3'],

        'price' => ['required', 'integer'],
    ]);

}

here code has unique value from table products. but whenever I edit the form it says code has already taken. so how to execute this without edit the 'code'(its unique).

Upvotes: 1

Views: 57

Answers (3)

bhavinjr
bhavinjr

Reputation: 1763

Try this, proper and clean code

ProductController

use Illuminate\Validation\Rule; // add this

public function store()
{
    $product = Product::create($this->validateRequest());

    return redirect('/product'); //use route instead of URL
}

public function update(Product $product)
{
    $product->update($this->validateRequest($product->id));

    return redirect('/product'); //use route instead of URL
}

private function validateRequest($id = null)
{
    return request()->validate([
        'sub_category_id' => 'required',
        'name' => 'required|min:4',
        'code' => 'required|alpha_dash|' . Rule::unique('products')->ignore($id),
        'description' => 'required|min:4',
        'color' => 'required|min:3',
        'price' => 'required|integer',
    ]);
}

Suggest to use Form request validation

Upvotes: 0

Rezuan Kassim
Rezuan Kassim

Reputation: 21

So the problem here is you are using the same rule for creating the product and updating the product.

If you are using the latest Laravel, you may want to read the documentation about form request https://laravel.com/docs/7.x/validation#form-request-validation and create different form request for store and update.

If you still want to use your way, you can try as below

private function validateRequest()
{
    $rules = [
        'sub_category_id' => ['required'],
        'name' => ['required', 'min:4'],
        'description' => ['required', 'min:4'],
        'color' => ['required', 'min:3'],
        'price' => ['required', 'integer'],
    ];
    
    if (request()->isMethod('store')) {
        $rules['code'] = ['required', 'alpha_dash'];
    }

    return request()->validate($rules);
}

Please tell me whether it works!

Upvotes: 0

Remul
Remul

Reputation: 8252

You can ignore certain ids during the unique check:

use Illuminate\Validation\Rule;

public function store()
{
    Product::create($this->validateRequest(new Product()));

    return redirect('/product');
}

public function update(Product $product)
{
    $product->update($this->validateRequest($product));

    return redirect('/product');
}

private function validateRequest(Product $product)
{
    return request()->validate([
        'sub_category_id' => ['required'],
        'name' => ['required', 'min:4'],
        'code' => ['required', 'alpha_dash', Rule::unique('products')->ignore($product)],
        'description' => ['required', 'min:4'],
        'color' => ['required', 'min:3'],
        'price' => ['required', 'integer'],
    ]);
}

Here you either pass the existing model when updating or a new model instance when storing, so the call to $product->id either returns null when storing a new product so no product in the database is ignored, or the id when updating and then only that product is ignored.

From the docs:

Forcing A Unique Rule To Ignore A Given ID:

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. You will probably 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.

To instruct the validator to ignore the user's ID, we'll use the Rule class to fluently define the rule. In this example, we'll also specify the validation rules as an array instead of using the | character to delimit the rules:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);

Be aware of the following though:

You should never pass any user controlled request input into the ignore method. Instead, you should only pass a system generated unique ID such as an auto-incrementing ID or UUID from an Eloquent model instance. Otherwise, your application will be vulnerable to an SQL injection attack.

Upvotes: 2

Related Questions