So I have a carbon field on my model called start_time
protected $dates = [
'created_at',
'updated_at',
'deleted_at',
'start_time'
];
And it all works well when creating a model or updating a model with a new start_time, but when I update the model without start_time changed, it changes it to the current date.
I have checked the input many times over and I am definitely sending the correct date to the update method, but if it's the same date and time then the model update changes it to the current date and time.
I have even resorted to sending the following to the update method to confirm that the issue is with the field being unchanged:
'start_time' => Carbon::createFromFormat('Y-m-d H:i', request('start_time'))->addMinutes(1)
By adding a minute to it it saves correctly.
Have a field set as a carbon field in the model $dates variable.
do a Model->update() with the field unchanged.
The field reverts to current time
I believe this is the same issue as #22498
As a workaround until the bug is fixedI have put this line before my actual update statement:
$model->update(['start_time' => Carbon::now()]);
Which then means my actual update works since start_time is now going to be dirty. I think the fact this workaround works further confirms the issue is as I explained above.
I'm also seeing this, no idea what's causing it.
@DeanStr your work around works, but I went with subtracting a second since my dates revolved around midnight.
I logged out the models date field from the controller and see the same thing DeanStr described.
```
// Without updating
[2018-01-26 20:32:29] local.DEBUG: 2018-01-02 04:59:59 // before save
[2018-01-26 20:32:29] local.DEBUG: 2018-01-26 20:32:29 // after save
// With updating
[2018-01-26 20:35:30] local.DEBUG: 2018-01-02 04:59:59 // before save
[2018-01-26 20:35:30] local.DEBUG: 2018-01-02 04:59:58 // after save
````
Can't replicate this.
Just out of curiosity do you have on update CURRENT_TIMESTAMP set for your datetime fields?
@arjasco
Didn't think I was but apparently the ->timestamp() migration defaults to CURRENT_TIMESTAMP even without ->useCurrent()
Checking my database properties after migration shows this.
Switching from timestamp() to dateTime() fixes this behavior
@DeanStr are you using timestamp() in your migration?
@Dewbud yes, also using timestamp()
So is this a bug with the timestamp() migration or just that it defaults to the current time is missing from the documentation?
Glad you guys figured it out. 👍
Are you running MySQL? and if so is it version >= 5.7.
See the Database section here on the older upgrade docs for 5.3 - https://laravel.com/docs/5.3/upgrade
Maybe this is apart of your problem.
I always have nullable timestamps and manage them myself if they should always have a value, I can't even run a migration with ->timestamp without it complaining i need a default value.
Locally I use sqlite, I guess that explains the no errors on migrations, however the issue is still present locally as well.
Production is mysql 5.7, however I've turned off strict mode due to another issue, but even before that I dont believe I had any issues when migrating.
In any case, I'd say there is a bug here in that:
@Dewbud @DeanStr ->timestamp() doesn't look like forcing CURRENT_TIMESTAMP without ->useCurrent()
You can take a look (MySqlGrammar.php line 638)
protected function typeTimestamp(Fluent $column)
{
$columnType = $column->precision ? "timestamp($column->precision)" : 'timestamp';
return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType;
}
I've tried it both on [5.4] and [5.5] using sqlite and I can't reproduce the issue.
$dates$dates = ['test'];
timestamp field$table->timestamp('test');
$user = User::create([
'name' => 'john',
'email' => 'john@email',
'password' => 'password',
'test' => Carbon::parse('2 weeks ago')
]);
I even tried passing a string to test
$user->update(['name' => 'jane']);
and
$user->update();
Both didn't alter the test field. $user->test always came as I saved when it was created.
Maybe I missed something, but I'll suggest looking on the side of the DB.
Can you replicate on a fresh install ?
Or somewhere there's a something forcing the hands of your timestamps.
I actually have no idea whether CURRENT_TIMESTAMP is being set as a default value, I just went off what @Dewbud said, how can I check that?
Like I said though, this is happening locally on sqlite and in production on mysql, do I doubt its a db issue, and since it's only happening when the timestamp value isn't dirty when sent to update I assume it's something in the laravel framework.
I can't replicate this, updating the model without changing the field doesn't change the value in the database.
I've had this happen before. Sometimes MySQL (depending on its SQL_MODE — I think?) will implicitly add DEFAULT CURRENT_TIMESTAMP or something as well as on update CURRENT_TIMESTAMP to the first timestamp column in a table matching this criteria:
I always make my timestamp columns nullable to get around this.
Closing then since it's not an issue in the framework.
I have the same issue too. Not sure what caused it.
I currently need to specify timestamp nullable and default null to prevent it.
I have the same issue too.
My custom end_date field updated when I call
$coupon->save();
Coupon is my model, field end_date is not touched in my code
Same issue here. It is clearly due to on update CURRENT_TIMESTAMP. Manually setting that to none fixes the issue, but the problem is that every time I refresh the DB on my local it set to on update CURRENT_TIMESTAMP again. Even more annoyingly this happens on local only, not in production, so it has clearly something to do with the MySql version/mode (as @thecrypticace assumed). Most likely the mode since we have same version on local/production.
Thanks @Dewbud
Switching fromtimestamp()todateTime()fixes this behavior
Most helpful comment