framework: [5.5] UPDATED_AT constant behavior breaking change

  • Laravel Version: 5.5.0
  • PHP Version: 7.1
  • Database Driver & Version: MySQL 5.7

Description:

I’ve used null UPDATED_AT contant in models where there were no updated_at column but something was changed in 5.5 and I couldn’t find this change in changelog. In 5.4 updated_at column was completely ignored on null value of constant. And now we have an exception:

Too few arguments to function Illuminate\Database\Eloquent\Model::setAttribute(), 1 passed

That happens because setAttribute method instead of updated_at column key receives empty string.

Found by @xdisplayx in one of my packages: https://github.com/cybercog/laravel-likeable/issues/24

Steps To Reproduce:

1. Create migration without updated_at column

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateEntitiesTable extends Migration
{
    public function up()
    {
        Schema::create('entities', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamp('created_at')->nullable();
        });
    }
}

2. Create Eloquent Model class

<?php

namespace App;

class Entity extends \Illuminate\Database\Eloquent\Model
{
    const UPDATED_AT = null;

    protected $fillable = [
        'name',
    ];
}

3. Try to create an Entity

$entity = Entity::create([
    'name' => 'Test',
]);

Result

Too few arguments to function Illuminate\Database\Eloquent\Model::setAttribute(), 1 passed

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 28 (23 by maintainers)

Most upvoted comments

I am not sure from where you got that idea to define const UPDATED_AT = null.

There are many undocumented features that are only found when reviewing the source code of the framework. Github is a good source to learn new things.

Hah… one more hack found. Just add to your model this method and keep $timestamps = true.

public function setUpdatedAt($value)
{
    return $this;
}

Seems strange. It works for me and @rodrigopedra confirmed this solution too: https://github.com/laravel/framework/issues/21045#issuecomment-327593582

Yup I thought so, this is why I ended up adding those fields even if I don’t use it. Thanks for letting me know.