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

fastforward's avatar

Eloquent update method returns false if nothing is changed.

Hello! Since i've upgraded laravel from 5.2 to 5.3 I got this weird bug in only one route, Eloquent update method returns false if nothing is changed on update. If atleast one field is changed everything works fine. I have no clue why this is happening and how to fix it, as I've tried debugging it with xdebug and it returns nothing, no errors nothing at all.

This is code which is somehow bugged.

 $forum->update([
    'title'          => $request->title,
    'description'    => $request->description,
    'needs_approval' => $request->needs_approval,
    'topic_reward'   => $request->topic_reward,
    'post_reward'    => $request->post_reward,
 ]);

I've tried fill()->save(); forceFill()->save(); and even OOP way, nothing works. Maybe anyone have similar issue and know how to fix it? Thanks!

0 likes
28 replies
fastforward's avatar

@Snapey I have code after it and if it returns false nothing after it is being called.

Snapey's avatar

you are testing the return value?

shez1983's avatar

if a user presses save without changing anything for example then redirect back with no message?

InaniELHoussain's avatar

As I understand, you said that the update method returns false if nothing is changed, and true if it did change a column?

fastforward's avatar

@shez1983 yes @InaniELHoussain If I don't change any value in form then it's returning false and code after it isn't being called, but if I change for example title value, everything works fine.

Snapey's avatar

it can't just skip past your code unless a branch is involved. Are you sure the update method is even called?

Is it a regular form post, or Ajax?

fastforward's avatar

@Snapey regular post and If it wouldn't be called, then it shouldn't update when atleast one field is changed.

shez1983's avatar

what code are you executing after that needs to be executed? just so we can give you better answer..

Snapey's avatar

sorry for being pedantic about this but you have only shared a short snippet and you say it returns 'false'. False is a specific state. how do you know it returns false? what gave you done to test what is passed to the model and what is returned? Where is this code? in a controller? show the entire file?

Snapey's avatar

ok, so how do you detect 'false'

fastforward's avatar

@Snapey return $forum->update([...]); = false if $request values are same as in database, true if atleast one is changed. Simple as that. I've now tested with Laravel Observers, and saved or updated event is not being triggered either if values are same as in database

InaniELHoussain's avatar

Why not making it in two steps

1// check if the Model exists a// check if the update is done a.1// if so flash that it has been updated successufully a.2// if not flash a message that the values are the same 2// if it doesnt exists flash an error message

fastforward's avatar

@InaniELHoussain Model binding already does this "checking if it exists". I don't need to show that values are same, I just need it to show as it was in 5.2, just return that forum was updated even if there wasn't any changes.

InaniELHoussain's avatar

@fastforward since you are using FormRequest its always 100% guarentee that it will be updated. so you only need to flash the message in the controller's method

Snapey's avatar

if the model is not 'dirty' then I can expect that the update does not bother writing to the database, particularly since you told it not to update the time stamps. The point is, when you call forum->update() it should ALWAYS return to your next line, the only exception being, well, exceptions.

It may return false but since you don't check the return value, there should not be a problem.

Snapey's avatar

if you comment out the update line, does your logging and flash always get called?

fastforward's avatar

@Snapey Yes they do, update is returning something similar to die(), when there are no changes for any of the fields, only return redirect() still works, but nothing else.

shez1983's avatar

i have never seen it done before like that? What is Forum $forum? a model?

cant you assign the value of forum->update() and check that? or if it causes the page to die() then use try / catch so that it doesnt stop execution of the page

fastforward's avatar

@shez1983 it's not causing page to die, but it acts similar to die or exit, only with one exception, return redirect still works, but nothing else and it happens only if any fields aren't changed. I tried already try / catch, still doesn't work. I don't know how to fix this and yes $forum is a Forum model.

ggwebdev's avatar

is easy, send with data the updated_at value, as this will always be different the update will return true even if they are the same data because the updated_at is different

fastforward's avatar
fastforward
OP
Best Answer
Level 1

@ggwebdev Hi, this is already fixed, seems like it was laravel issue, as I updated my laravel to latest version and this issue disappeared.

ab_mannan's avatar

@fastforward I just stumbled upon this scenario and the composer update didn't do the trick in my case.

I have a Certification Model that has the save function in which i am doing something like this

$saveCertData = CertificationModel::where('id', $certId)->update($certData);

and when I DD the $saveCertData, it outputs "0" if there is no change in the record whereas it outputs "1" if there is any change. And I am performing the check that if the record is successfully updated, then perform further things.

And that scenario is failing just because of that UPDATE call that is returning "0" even if the query executes without any error.

Any other possible workaround for this?

hsntngr's avatar

having the same reaction with laravel 5.7 using DB facade

ajayidavid99's avatar

Haven't gotten into the detail of this but what is happening is: Your call may not necessarily be returning false but Larvel Query builder update returns the number of updated lines. So if nothing is unchanged, updated lines is zero. And 0 returns false(checking 0 (int) with the not (!) operator) and the one way around this is to use the try catch block. Something like this: try { // Get the updated rows count here. Keep in mind that zero is a // valid value (not failure) if there were no updates needed $count = DB::table('users')->update([ 'active' => true ]); } catch (\Illuminate\Database\QueryException $e) { // Do whatever you need if the query failed to execute }

Please or to participate in this conversation.