Laravel Eloquent: How to cast data types of model attributes

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

Introduction

With the rise of complex web applications, managing data types in a relational database becomes crucial. Laravel, an elegant PHP framework, simplifies this management task using ‘Eloquent’ which is an Object Relational Mapper (ORM). Eloquent allows for seamless interaction with databases by taking advantage of Model classes. In this guide, we will walk through the process of data type casting in Laravel Eloquent to ensure integrity and consistency of data throughout your application.

When retrieving or setting attribute values on Eloquent model instances, you can ensure they are of the correct data type by defining type casts in your model. Casting comes into play when you are dealing with different data types like boolean, integers, floats, array, JSON, or even date and time objects. Let’s explore what attribute casting is, why it’s useful, and how you can implement it in your Laravel models.

Understanding Attribute Casting

In Eloquent, casting an attribute implies converting that attribute to a common data type before storing or retrieving it from the database. Eloquent offers a convenient attribute casting feature whereby you can define how each attribute should be cast when retrieved from or set to the database.

Let’s consider a simple example: imagine you have a model ‘User’ with an attribute ‘is_subscribed’ which is stored in your database as an integer (1 for true, 0 for false). You might want this to be treated as a boolean when you work with a User instance in your app-instead of having to manually cast it every time you access it. Here’s where Eloquent casting comes into play. By defining a cast for this attribute in your User model, you can interact with ‘is_subscribed’ as if it were a boolean.

How to Define Casts in Your Model

To tell Eloquent how to cast your attributes, add a $casts property to your model:

class User extends Model {
    protected $casts = [
        'is_subscribed' => 'boolean',
    ];
}

The $casts property should be an array where the key is the name of the attribute and the value is the type you wish to cast it to. The available cast types in Laravel include ‘int’, ‘real’, ‘float’, ‘double’, ‘string’, ‘bool’, ‘boolean’, ‘object’, ‘array’, ‘collection’, ‘date’, ‘datetime’, and ‘timestamp’.

Advanced Casting: Custom Cast Classes

Laravel also allows for the definition of custom cast types using classes that implement the CastsAttributes interface. This approach is useful for more complex casting scenarios. Let’s create a custom cast that automatically serializes and deserializes a JSON attribute into a specific PHP object.

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class AddressCast implements CastsAttributes
{
    public function get($model, $key, $value, $attributes)
    {
        return new Address(json_decode($value, true));
    }

    public function set($model, $key, $value, $attributes)
    {
        return json_encode($value);
    }
}

class User extends Model {
    protected $casts = [
        'address' => AddressCast::class,
    ];
}

Now every time you retrieve the ‘address’ attribute from a User model, it will return an Address object and the reverse will happen when you set that attribute.

Casting Dates and Times

Eloquent also provides a cast type specifically for date and time, which returns instances of Carbon, a PHP date manipulation library. This means you can easily perform date calculations, formatting, and manipulation right on the attribute like so:

class User extends Model {
    protected $casts = [
        'created_at' => 'datetime:Y-m-d', // Will return a formatted date
    ];
}

If you only need to customize the format of a date attribute, Laravel provides the $dateFormat property which you can set in your model:

class User extends Model {
    protected $dateFormat = 'U';
}

This will ensure that the retrieved date is formatted as a Unix timestamp. It’s important to note that defining a $dateFormat will affect how dates are stored in and retrieved from the database.

Dealing with JSON

Given the ubiquity of JSON data structures, Laravel offers a simple way to cast attributes to JSON and vice versa. This allows you to store arrays or objects as JSON strings in the database, and automatically have them returned as PHP arrays or objects when accessing the attribute in question.

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

With the ‘options’ attribute cast to an array, you can directly access the data as if it were a regular PHP array, and any changes will automatically be converted to a JSON string when the model is saved to the database.

That’s it. This tutorial ends here. Happy coding & have a nice day!