How to set a default attribute value for a Laravel / Eloquent model?

PhpModelLaravelLaravel 4Eloquent

Php Problem Overview


If I try declaring a property, like this:

public $quantity = 9;

...it doesn't work, because it is not considered an "attribute", but merely a property of the model class. Not only this, but also I am blocking access to the actually real and existent "quantity" attribute.

What should I do, then?

Php Solutions


Solution 1 - Php

An update to this...

@j-bruni submitted a proposal and Laravel 4.0.x is now supporting using the following:

protected $attributes = array(
  'subject' => 'A Post'
);

Which will automatically set your attribute subject to A Post when you construct. You do not need to use the custom constructor he has mentioned in his answer.

However, if you do end up using the constructor like he has (which I needed to do in order to use Carbon::now()) be careful that $this->setRawAttributes() will override whatever you have set using the $attributes array above. For example:

protected $attributes = array(
  'subject' => 'A Post'
);

public function __construct(array $attributes = array())
{
    $this->setRawAttributes(array(
      'end_date' => Carbon::now()->addDays(10)
    ), true);
    parent::__construct($attributes);
}

// Values after calling `new ModelName`

$model->subject; // null
$model->end_date; // Carbon date object

// To fix, be sure to `array_merge` previous values
public function __construct(array $attributes = array())
{
    $this->setRawAttributes(array_merge($this->attributes, array(
      'end_date' => Carbon::now()->addDays(10)
    )), true);
    parent::__construct($attributes);
}

See the Github thread for more info.

Solution 2 - Php

This is what I'm doing now:

protected $defaults = array(
   'quantity' => 9,
);

public function __construct(array $attributes = array())
{
    $this->setRawAttributes($this->defaults, true);
    parent::__construct($attributes);
}

I will suggest this as a PR so we don't need to declare this constructor at every Model, and can easily apply by simply declaring the $defaults array in our models...


UPDATE:

As pointed by cmfolio, the actual ANSWER is quite simple:

Just override the $attributes property! Like this:

protected $attributes = array(
   'quantity' => 9,
);

The issue was discussed here.

Solution 3 - Php

I know this is really old, but I just had this issue and was able to resolve this using this site.

Add this code to your model

protected static function boot()
{
   parent::boot();

   static::creating(function ($model) {
        $model->user_id = auth()->id();
    });
}

Update/Disclaimer

This code works, but it will override the regular Eloquent Model creating Event

Solution 4 - Php

Set attribute value whit construct

  public function __construct()
    {
        $this->attributes['locale'] = App::currentLocale();
    }

Solution 5 - Php

I use this for Laravel 8 (static and to dynamically change attributes)

<?php

namespace App\Models\Api;

use Illuminate\Database\Eloquent\Model;

class Message extends Model
{
    /**
     * Indicates if the model should be timestamped.
     *
     * @var bool
     */
    public $timestamps = false;


    protected static function defAttr($messages, $attribute){

        if(isset($messages[$attribute])){
            return $messages[$attribute];
        }

        $attributes = [ 
            "password" => "123",
            "created_at" => gmdate("Y-m-d H:i:s"),
        ];

        return $attributes[$attribute];
    }
    

    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::creating(function ($messages) {
            $messages->password = self::defAttr($messages, "password");
            $messages->created_at = self::defAttr($messages, "created_at");
        });
    }

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJ. BruniView Question on Stackoverflow
Solution 1 - PhpcmfolioView Answer on Stackoverflow
Solution 2 - PhpJ. BruniView Answer on Stackoverflow
Solution 3 - PhppbgneffView Answer on Stackoverflow
Solution 4 - PhpUriel Acosta HernándezView Answer on Stackoverflow
Solution 5 - Php Юрий СветловView Answer on Stackoverflow