Eloquent: Create model with default values

Updated: January 16, 2024 By: Guest Contributor Post a comment

Introduction

When working with Laravel’s Eloquent ORM, one might wish to define default values for a model’s attributes. Eloquent provides an eloquent way to set these default values, ensuring a smoother development process and fewer errors down the line. In this tutorial, we’ll walk through the steps to create models with default values, from basic usage to applying more advanced scenarios.

Before diving in, please ensure that you have Laravel installed and you are familiar with the basics of Model creation and migrations in Laravel.

Basic Usage

To define default values for your Eloquent model, you can declare a protected $attributes property on the model class. Here’s a simple example:

class Post extends Model {
    protected $attributes = [
        'views' => 0,
        'is_published' => false,
    ];
}

Now, when you create a new Post instance, it will have 0 views and not be published by default:

$post = new Post();
echo $post->views; // Output: 0
echo $post->is_published ? 'Yes' : 'No'; // Output: No

Specifying Defaults in Migrations

Another way to set default values is during the database migration phase. For example, you could set a default in your migrations file like this:

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->integer('views')->default(0);
    $table->boolean('is_published')->default(false);
    $table->timestamps();
});

This will ensure that the default values will be applied at the database level every time a new row is inserted, regardless of whether a model instance was used to create it.

Advanced Usage

Let’s go a step further with Eloquent. Sometimes you’ll want to have complex default values, possibly even based on other attributes of the model. An Eloquent model fires several events, allowing you to hook into places like creating and saving, to manipulate attributes.

If we want a default title for a blog post that includes the creation date, we can add an observer method:

protected static function booted() {
    static::creating(function ($post) {
        $post->title = $post->title ?? 'Post on ' . now()->toDateString();
    });
}

The static booted method is called when the model is booting up and within it, we can add listeners. In this case, if there’s no title when we are creating the Post, set it to ‘Post on [today’s date]’.

Attribute Casting

In some cases, you may also need to ensure that the defaults are cast correctly based on the defined casts in the model. For example, you might use JSON casting and want to ensure that you have a default array structure:

class User extends Model {
    protected $casts = [
        'options' => 'array',
    ];

    protected $attributes = [
        'options' => '{"theme": "default"}',
    ];
}

Now, when you use the options attribute, it will be an array by default:

$user = new User();
print_r($user->options); // Output: Array ( [theme] => default )

It’s important to provide a JSON string in the $attributes array – since that’s what will get cast into an array by the Eloquent model.

Conclusion

Setting default values for models in Laravel Eloquent is a good practice for relaying intentions and ensuring data integrity. By leveraging Eloquent’s features – such as the $attributes array, database migration defaults, attribute casting, and lifecycle events – we’ve learned how to establish robust defaults for our models at both the application and database levels. Utilizing these approaches can lead to cleaner, more maintainable code bases.