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

Ashraam's avatar

created_at fields updated when saving

Hi everyone,

I have this little problem and I can't find the answer or why it's doing this.

Let say that I created an article, the created_at and updated_at are currently the same, this is ok.

Now when I update this article, the created_at and updated_at fields are modified to the current timestamps, but in my logic the created_at field shouldn't be updated. Also I don't know why but updated_at field = created_at field minus 1 hour...

Here is my controller who update the article:

public function update($id, ArticleRequest $request) {
        $article = Article::findOrFail($id);    
        $article->update($request->all());      
        return Redirect('/articles/'.$id);
    }

Can someone help me ? Thanks

0 likes
25 replies
t0berius's avatar

Aren't you explicit updating ALL values (in case they exist in your request)? The updated_at and created_at field didn't need to exist. As in the database defined laravel will set them they will be set to the current timestamp. In my point of view you need to pass each "field" to be updated.

All the best;

InaniELHoussain's avatar

you have to use the save method,

$article->body = $request->body; $article->save();

Ashraam's avatar

But isn't mass assignment should prevent this ?

In my Article Model, i've created a variable $fillable and there are no created_at nor updated_at fields in it.

InaniELHoussain's avatar

@Ashraam both created_at & updated_at are set to the current time on UPDATE method (its by defenition)

the Timestamps are handled by laravel, so u don't have to mention it in the $fillable property.

the solution is to use the save method As I mentioned before.

Ashraam's avatar

@AkiyamaSmart Ok, I've changed the my method like this:

public function update($id, ArticleRequest $request) {
        $article = Article::findOrFail($id);

        $input = $request->all();
        
        $article->title = $input['title'];
        $article->text = $input['text'];
        $article->published_at = $input['published_at'];
        $article->save();
        
        return Redirect('/articles/'.$id);
    }

Same problem, both created_at and updated_at fields have been updated to the same time (minus 1 hour to the updated_at field ???)

joedawson's avatar

created_at shouldn't be updated when you're saving your article, I'm not quite sure why that's happening though as what you have in your original post seems correct to me. I'm not sure where @AkiyamaSmart got the information about the created_at timestamp being updated when a model is updated because this is incorrect.

Regarding the time being minus one hour, ensure you have set the timezone in your config/app.php file. I have mine set to Europe/London to ensure I get the correct timestamps. So be sure to update this to the correct Timezone for your app.

joedawson's avatar

@AkiyamaSmart for as long as I've used Laravel, this has never worked this way which is why I was so convinced I was correct. This does not make sense to be that the created_at timestamp is updated.

1 like
Ashraam's avatar

Thanks for help @AkiyamaSmart

Thank you @JoeDawson I've updated my timezone in config/app.php, it solve this problem.

But still, I don't get it. Why Laravel would update created_at fields on update :s

1 like
Ashraam's avatar

@JoeDawson

Here is my article migration

 public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->string('title');
            $table->text('text');
                    $table->timestamps();
        });
    }

I've read the article linked by @AkiyamaSmart and I also tried to update an user. Same issue here, it's probably coming from the database. When I look the my table structure there is this in the default column of created_at field:

CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

Instead of using $table->timestamps() I tried to create them like this:

$table->timestamp('created_at');
$table->timestamp('updated_at');

But same problem in any cases

Ashraam's avatar

thank you @ohffs this is working !

They should upgrade Artisan when making new migration !

1 like
ohffs's avatar

Yeah - there seem to have been more changes in 5.1 -> 5.2 that break existing code/workflows than I would have expected in a feature release (the semver guidance says 'MINOR version when you add functionality in a backwards-compatible manner').

I hate to think how many laravel tutorials out there on the web (or even on here) are now broken with 5.2... :-/

Ashraam's avatar

Sure, I starting to learn lavavel with Jeff videos, some of them are already outdated :/

ohffs's avatar

I don't mind things like 4 -> 5 making breaking changes and making tutorials out-dated (although another pet peeve is tutorials which don't indicate a version, but that's another matter). But things like $errors not always being set is really irritating - such a small thing, but will break code for 1000's of people.

It's still referenced in the docs too : 'So, it is important to note that an $errors variable will always be available in all of your views on every request, allowing you to conveniently assume the $errors variable is always defined and can be safely used' :-/

1 like
Jafo232's avatar

This really broke some stuff on an app of mine. Any idea what query should be used to fix an existing table without dropping columns?

Jafo232's avatar

Well, here is how I fixed it and migrated it, to each of my existing timestamped tables for up:

DB::statement('ALTER TABLE users MODIFY COLUMN created_at  timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; ALTER TABLE users MODIFY COLUMN updated_at timestamp NULL DEFAULT \'0000-00-00 00:00:00\'');

And for down:

DB::statement('ALTER TABLE `users` MODIFY COLUMN `created_at`  timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, MODIFY COLUMN `updated_at`  timestamp NOT NULL DEFAULT \'0000-00-00 00:00:00\' AFTER `created_at`;');
Jafo232's avatar

Well, nevermind. When I update a table, it is updating created_at at the same time.. Sigh.. This sucks..

arashlaghaei90's avatar

hi every body i fixed problem create_at please do it: vendor/laravel/framework/srs/illuminate/database/schema/blueprint.php line:792

 public function timestamps()
{
    $this->timestamp('updated_at');

    $this->timestamp('created_at')->useCurrent();

}

please do it exactly i write. and fix this problem.

morshah's avatar

I replaced:

$table->timestamps();

With

$t->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$t->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'));

Based on How can I set the default value of a timestamp ...

Paulo Freitas makes the point that starting with MySQL 5.7, 0000-00-00 00:00:00 is no longer considered a valid date, so I set updated_at to CURRENT_TIMESTAMP rather than 0000-00-00 00:00:00.

aitbenhaanass's avatar

I think the Problem is that the time zone set on your config/app.php is not the same as the time zone on your database ; the update / create methode uses the current timestamp of DB

Please or to participate in this conversation.