107

How to set the default value of an attribute on a Laravel model?

Should I set the default when creating a migration or should I set it in the model class?

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Zeeshan Bin Iqbal
  • 1,206
  • 2
  • 8
  • 8
  • http://stackoverflow.com/questions/18747500/how-to-set-a-default-attribute-value-for-a-laravel-eloquent-model – StateLess Oct 07 '16 at 08:06

3 Answers3

167

You can set Default attribute in Model also>

protected $attributes = [
        'status' => self::STATUS_UNCONFIRMED,
        'role_id' => self::ROLE_PUBLISHER,
    ];

You can find the details in these links

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

2.) https://laracasts.com/index.php/discuss/channels/eloquent/eloquent-help-generating-attribute-values-before-creating-record


You can also Use Accessors & Mutators for this You can find the details in the Laravel documentation 1.) https://laravel.com/docs/4.2/eloquent#accessors-and-mutators

2.) https://scotch.io/tutorials/automatically-format-laravel-database-fields-with-accessors-and-mutators

3.) Universal accessors and mutators in Laravel 4

Community
  • 1
  • 1
Manish
  • 3,443
  • 1
  • 21
  • 24
  • thanks, setting default attribute works fine as protected $attributes = [ 'status' => self::STATUS_UNCONFIRMED, 'role_id' => self::ROLE_PUBLISHER, ]; but as Mutators it didn't work e.g. public function setUserTypeAttribute($value){ $this->attributes['user_type'] = 'User'; } i want to ask if there is any difference b/w these approaches, or which one is best. – Zeeshan Bin Iqbal Oct 07 '16 at 10:36
  • Both are better. Its up to you. In mutator i gave you an example where you can set default value in case of `empty or custom` made condition.like `public function setUserTypeAttribute($value){ $this->attributes['user_type'] = empty($value) ? 'User' : $value; }` I hope you got my point with this example. – Manish Oct 07 '16 at 11:02
  • @Zeeshan Bin Iqbal Did this solve your issue? – Manish Oct 07 '16 at 14:24
  • 12
    Using a mutator won't quite work because the mutator only gets called when you assign a value to the attribute. So if you never assign a value to that attribute at all, it won't actually have the default value that you want it to. – orrd Jun 13 '18 at 18:38
  • I wish I could upvote you twice. – Mauro Nov 20 '18 at 19:03
  • @Mauro Your appreciation is more than any up vote. Thanx – Manish Nov 21 '18 at 14:05
  • Well, theoretically setting default values in database will improve performance slightly, but it is too little to be even taken into consideration. If you delare them in the model, it will also be used while creating a new model instance for eg. when using a make() statement. So use it based on your requirements. – Ahmed Shefeer Mar 19 '20 at 07:04
52

The other answers are not working for me - they may be outdated. This is what I used as my solution for auto setting an attribute:

/**
 * The "booting" method of the model.
 *
 * @return void
 */
protected static function boot()
{
    parent::boot();

    // auto-sets values on creation
    static::creating(function ($query) {
        $query->is_voicemail = $query->is_voicemail ?? true;
    });
}
TenMedia
  • 3
  • 1
  • 2
parker_codes
  • 3,267
  • 1
  • 19
  • 27
  • this is awesome – caro Jul 27 '18 at 14:00
  • 1
    I should also specify that I try to use default values in migrations. This example above is from a Voicemail model which is extending a Recording model, so they use the same table. When a new Voicemail model is created, is_voicemail is set to true. – parker_codes Jul 27 '18 at 14:46
  • 2
    i just needed to set a value IF it comes through on create as null, so this worked great for me – caro Jul 27 '18 at 15:53
  • This is a great solution for the insanity of not being able to set a default value of a blank string for a text column: https://stackoverflow.com/questions/3466872/why-cant-a-text-column-have-a-default-value-in-mysql – Inigo Dec 18 '19 at 18:07
  • Nice solution. Where can I find documentation of this? – nishil bhave May 16 '20 at 09:11
  • 1
    @nishilbhave https://github.com/laravel/framework/blob/7.x/src/Illuminate/Database/Eloquent/Model.php#L212 https://laravel.com/docs/7.x/eloquent#events – parker_codes May 16 '20 at 15:18
  • 1
    Smartest thing I've seen on stackoverflow up to now! – Steve Moretz Jun 27 '21 at 15:43
  • Very nice. This answer also handles the situation where you want to assign default values that are complex and computed, for example, a `UUID` string since you can't assign the value of `Str::uuid()` directly into the `$attributes` property. – Eyad Mohammed Osama Apr 17 '23 at 09:13
12

You should set default values in migrations:

$table->tinyInteger('role')->default(1);
Alexey Mezenin
  • 158,981
  • 26
  • 290
  • 279
  • 5
    For example, when using models for form validation you want to have a default value before saving it to the database. When using your example, you need to add the record to the database before being able to retrieve the default value, which is cumbersome. – Inserve Jun 02 '17 at 15:14
  • Not to mention that _some_ column types don't allow defaults (such as text) – Chris Jan 01 '18 at 06:42
  • 16
    The question asks, how to set the default value on a model. It does not ask how to set the default value in the database. These are different things, and many times you may want to `new` a model without reference to the database – Snapey Sep 02 '18 at 15:29
  • 1
    Whereas this may be the appropriate best practice for a RDBMS, the OP doesn't specify which database he is using. In a schemaless setup, this doesn't apply. – aowie1 Nov 07 '18 at 19:29
  • Some RDBMSs (e.g. MySQL < 8.0) only support constants as default value for a field, with no support for expressions. Imagine you have a _year_ field and you would like the default value to be the current year. In such case your best option is probably to use application code (Laravel model), to supply that default value. – sudoqux Mar 03 '20 at 08:03
  • in migrations is the best place if it's a static value. For calculated values, the boot method is the way to go – woens Aug 18 '21 at 22:05
  • You might need to add a "->change()" to the end of this line, like this: $table->tinyInteger('role')->default(1)->change() – Magmatic Mar 24 '22 at 14:51