2

With a very simple model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Example extends Model
{

}

And it's schema for completeness:

<?php

use App\Models\Lease;
use App\Models\Choice;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTableExamples extends Migration {

    public function up()
    {
        Schema::create('example', function(Blueprint $table)
        {
            $table->increments('id');
            $table->enum('status', [1, 2, 3])->default(1);
            $table->text('abc')->nullable();
            $table->text('foo')->nullable();
        });
    }

    public function down()
    {
        Schema::dropIfExists('example');
    }
}

Why does the following save statement, result in empty attributes for the fields that are defined with defaults?

$example1 = new App\Models\Example();
$example1->foo = "BAR";
$example1->save();

var_dump($example1->attributes);

This outputs the following, note that the output has skipped the status field. Also note that field abc is missing.

array (size=4)
    'foo' => string 'BAR' (length=3)
    'id' => int 19

If I reload the model, with $example1->fresh(), I get the expected output:

array (size=4)
    'foo' => string 'BAR' (length=3)
    'abc' => null,
    'status' => int 1,
    'id' => int 19

Is there a way to avoid the fresh method? Under the hood, fresh is another trip to the db.

Chris
  • 54,599
  • 30
  • 149
  • 186

2 Answers2

1

You may try to set the defaults in your Model additionally (or exclusively) as suggested in other posts: How to set a default attribute value for a Laravel / Eloquent model?

This works for me in a Laravel 5.1 installation:

class Example extends Model
{
    protected $attributes = [
        'status' => 1
    ];
}

However, if you consider your DB as the only source of truth (and are setting the defaults there), it might be safer to get a fresh instance from it. If you look into Eloquent's save() you will find that it does not fetch the updated/inserted record (and afaik, some databases as mysql do not support returning the record upon insert/update within a single call - you might use a stored procedure though).

Community
  • 1
  • 1
macghriogair
  • 1,431
  • 10
  • 8
0

Eloquent Model has getOriginal() method which returns model's original attribute values.

Just tested it and it returns all columns with values. So it will be:

$example1 = new App\Models\Example();
$example1->foo = "BAR";
$example1->save();

var_dump($example1->getOriginal());

https://laravel.com/api/5.1/Illuminate/Database/Eloquent/Model.html#method_getOriginal

Muhammet
  • 3,288
  • 13
  • 23