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

ACH's avatar
Level 1

Checking if model has changed by other user

I have a Post model and an edit.blade to change the status on this. If two users updates the status simultanously I want the latest to fail. I though I could use isClean()/isDirty() for this but it seems like this only works withing the current request cycle, which I guess means for the same user session. So I am now trying to check if there is a newer update on the same record.

The the form to update the status looks like this:

<form method="POST" action="{{ route('selvbetjentUpdate', $post) }}">
    @csrf
    <th class="py-4 px-6"> Status <br/> ("Code sent"=>send mail)</th>
    <td class="py-4 px-6">
        <div class="mt-1 border rounded-lg">
            @foreach ($statuses = App\Models\ResponseStatus::where('request_type_id', 1)->get() as $status)
                <input id="{{ $status->id }}" type="radio" name="status" value="{{ $status->id }}" {{($post->responseStatus->description==$status->description) ? 'checked' : ''}}/>
                    <label for="{{ $status->id }}">{{$status->description}}</label><br>
            @endforeach
        </div>
    <tr>
        <th class="py-4 px-6"> &nbsp </th>
        <td>
            <x-jet-button class="ml-4">
                {{ __('Sett status / send mail') }}
            </x-jet-button>
        </td>
    </tr>
</form>
	

My controller update method looks like this:

public function update(CustDeliveryPost $post)
{
    $id=request()->input('status');
    $kode=request()->input('code');
    $latestPost=CustDeliveryPost::where('id', $post->id)->first();
    if ($latestPost->updated_at == $post->updated_at) { // WHY IS NOT THIS WORKING?
        $post->response_status_id=$id;
        $post->save();
        if ($id==2) { //status="code sent"
            $reply=new SelfserviceReply($kode, $container);
            $reply->subject('Code... ');
            Mail::to($post->epost)->send($svar);
        }
        return view('/custdeliveryposts.update', ['id', $post->id]);
    }
    else { // Someone else changed the status before you
        return view('/custdeliveryposts.updateFail');
    }
}

Why doesn't my if statement to check if record was altered after read work: if ($latestPost->updated_at == $post->updated_at)?

0 likes
3 replies
kokoshneta's avatar

Why doesn't my if statement to check if record was altered after read work?

How do you know it doesn’t? What does it do? Do you get an error message? Which one? Have you tried dump()ing the two values you’re comparing to see if they’re actually the same or not?

Snapey's avatar
Snapey
Best Answer
Level 122
if ($latestPost->updated_at == $post->updated_at) { // WHY IS NOT THIS WORKING?

because $post that is injected into the controller has literally JUST been fetched from the database by route model binding. You then load a second copy of exactly the same record a few microseconds later.

Suggestion

When you load the edit page, send the updated_at field in a hidden field to the form.

When the form is submitted, get the post and check if the updated_at is still the same value that you sent to the form. If it is different then someone else has updated the record whilst this user had the page loaded.

(make sure your post does not have other reasons to be updated, such as a view counter being incremented)

1 like

Please or to participate in this conversation.