Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

SYPOMark's avatar

Validation on update

Hi there,

I've looked through the other posts on this issue and while there are some that do approach a similar issue, I'm afraid I've not been able to find one that quite matches what I'm after.

Here's the situation:

I'm building a form in Laravel Spark that allows the user to upload details about their stuff. In this form, they can assign a title, a category and a reference number. The validation at the point of creating the listing of the new item checks to see if another item already exists that has the same reference number assigned under the same category. So, two items can have the same reference number, but only if they belong to different categories.

The point at which the item is added to the database, what I currently have works great! But, when I want to update it, the validator says that the reference number already exists alongside a particular named category. Of course, a user doesn't want to have to change the reference number just because it's already been used for THAT item!

Anyway, an extract from the StuffRequest file looks like this:

<?php

namespace Laravel\Spark\Http\Requests\Settings\AddStuff;

use Laravel\Spark\Spark;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Http\FormRequest;

class StuffRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validator for the request.
     *
     * @return \Illuminate\Validation\Validator
     */
    public function validator()
    {
        return Validator::make($this->all(), [
            ...
            'reference_number' => 'required|max:50|unique:stuff,reference_number,NULL,id,category,' . FormRequest::get('category') . ',stuff_deleted,n',
            ...
        ]);
    }

I've already established that the way I've set up the route for the update probably needs altering, so that the update form uses a difference request file - eg StuffUpdateRequest - but, I don't know what should go in to check on this particular bit of validation.

In short: the validator on update still needs to check that the reference number is unique and not already assigned to the same category, but it also needs to allowed to pass if the reference number remains unchanged.

I hope that makes sense and I welcome any questions/comments/help that anyone can provide.

With kind regards,

Mark

0 likes
6 replies
aardalich's avatar

A way I have tackled this is have 2 view files, one for your create and one for your edit.

Have a hidden input in the the create and edit views declaring say an action value to create/edit.

Have the main body of the form within another file so you can @include it in both views

Then in your FormRequest, first check the hidden value if you are performing a create or edit and adjust your validation rules accordingly.

SYPOMark's avatar

@aardalich Thanks for getting back to me so quickly.

That sounds like a great solution. I take it that would also work where a modal is used for update form? Would you please be able to share your code for the validation?

With kind regards,

Mark

SYPOMark's avatar

@st8113 Thanks for your reply.

That looks like that's pretty close to what we're after, but how can I use this in a way that also checks on the category, and uses an id other than user id? In our example, it's stuff id.

With kind regards,

Mark

SYPOMark's avatar

@st8113 & @aardalich Thanks again for your answers. Whilst they tell me what to do, the how, unfortunately, alludes me.

Please could you share some code examples of how to achieve what you suggest in our specific case?

With kind regards,

Mark

aardalich's avatar

There are many ways you could achieve it

One example would be, pass an 'action' value in to your views

Create

return view('stuff.create_or_edit', ['action' => 'create']);

Edit

return view('stuff.create_or_edit', ['action' => 'edit']);

in your view, store the action in your form

<form method="POST" action="{{ route('stuff.store') }}>
    <input type="hidden" name="action" value="{{ $action }}">
    @if($action == 'create')
        <button type="submit" class="btn">Create Stuff</button>
    @else
        <button type="submit" class="btn">Update Stuff</button>
    @endif
</form>

and in your controller store method

// Rules which apply to both
$rules = [
    'name' => 'required'
];

// Rules which apply to create
if (request('action') == 'create' {
    $rules['create_field_to_validate'] = 'required';
}

$this->validate(request(), $rules);

Or if that's too messy for your controller, create a request class

php artisan make:request

and bundle up that logic in the request class as per https://laravel.com/docs/5.4/validation#form-request-validation

Another way is to have seperate create and view forms and include the main form within. You could even have each type go to a different action route and keep your validation for each type contain in their own controller methods.

In your controller method for create, return your create view

return view('stuff.create');

In your create view, include the guts of your form and pass in an action and possibly what to have on your submit button

<form method="POST" action="{{ route('stuff.create_store') }}">
    
    @include('stuff.partials._form', ['action' => 'create', 'buttonText' => 'Create Stuff'])

</form>

In your controller method for edit, return your edit view passing in your model data

return view('stuff.edit')->with(compact('stuff'));

the edit view

<form method="POST" action="{{ route('stuff.edit_store') }}">
    
    @include('stuff.partials._form', ['action' => 'edit', 'buttonText' => 'Update Stuff'])

</form>

You can do different things in your _form view you include in depending on the action

@if ($action == 'edit')
    <input type="hidden" name="id" value="{{ $stuff->id }}">
@endif

<button type="submit" class="btn">{{ $buttonText }}</button>

There's no right or wrong way. Comes down to what feels right for what you're working on and how it feels to you.

You may find you'll do it one way now, and a compete different way in 6 months after you have some mileage under your belt. :)

Please or to participate in this conversation.