Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel changes created_at on update

I found this answer on the subject, but it doesn't work for me.

So, I make an entry in the database:

// Write lead to database
$lead = Lead::create($lead_data);

And the timestamps look like this, which is good:

| 2016-01-08 10:34:15 | 2016-01-08 10:34:15 |

But then I make a request to an external server, and I need to update the row:

$lead->user_id = $response['user_id'];
$lead->broker_id = $response['broker_id'];
$lead->save();

and the created_at field gets changed:

| 2016-01-08 04:34:17 | 2016-01-08 10:34:17 |

How do I solve this problem?

EDIT

I need a solution that would just modify the behavior without dropping columns or resetting migrations. The fix has to be performed on a live database without touching the data. As suggested below, I tried the following migration:

$table->datetime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'))->change();

but nothing happens. The created_at field still gets modified on update.

like image 522
Skatch Avatar asked Jan 08 '16 09:01

Skatch


1 Answers

If you're on Laravel 5.2 and using MySQL, there was a bit of a "bug" introduced with the timestamps. You can read all about the issue on github here. It has to do with the timestamp defaults, and MySQL automatically assigning DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes under certain conditions.

Basically, you have three options.

  1. Update MySQL variable:

If you set the explicit_defaults_for_timestamp variable to TRUE, no timestamp column will be assigned the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes automatically. You can read more about the variable here.

  1. Use nullable timestamps:

Change $table->timestamps() to $table->nullableTimestamps(). By default, the $table->timestamps() command creates timestamp fields that are not nullable. By using $table->nullableTimestamps(), your timestamp fields will be nullable, and MySQL will not automatically assign the first one the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes.

  1. Define the timestamps yourself:

Instead of using $table->timestamps, use $table->timestamp('updated_at'); $table->timestamp('created_at'); yourself. Make sure your 'updated_at' field is the first timestamp in the table, so that it will be the one that is automatically assign the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes.

like image 186
patricus Avatar answered Sep 22 '22 16:09

patricus