PHP

Customizing Eloquent Attribute Data Types with Casting

Master custom attribute casting in Laravel Eloquent to automatically convert model attributes to specific PHP data types or objects like arrays or custom classes when accessed.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Casts\JsonToArrayStringCast;
use Illuminate\Database\Eloquent\Casts\AsCollection;
use Illuminate\Support\Collection;

class Settings extends Model
{
    protected $fillable = ['user_id', 'preferences', 'features'];

    // Define attribute casts
    protected $casts = [
        'preferences' => 'array', // Casts JSON string to PHP array and vice-versa
        'features' => AsCollection::class, // Casts JSON string to Laravel Collection object
        'is_admin_flag' => 'boolean', // Casts 0/1 to boolean true/false
        'last_login_at' => 'datetime', // Casts timestamp/string to Carbon instance
        'custom_setting_object' => JsonToArrayStringCast::class // Using a custom cast class
    ];

    // If you define a custom cast class (App\Casts\JsonToArrayStringCast.php):
    // namespace App\Casts;
    // 
    // use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
    // 
    // class JsonToArrayStringCast implements CastsAttributes
    // {
    //     public function get($model, $key, $value, array $attributes)
    //     {
    //         return json_decode($value, true);
    //     }
    // 
    //     public function set($model, $key, $value, array $attributes)
    //     {
    //         return json_encode($value);
    //     }
    // }
}

// Usage in a controller or elsewhere:

namespace App\Http\Controllers;

use App\Models\Settings;
use Illuminate\Http\Request;

class SettingsController extends Controller
{
    public function manageSettings()
    {
        // Create or find settings for a user
        $settings = Settings::firstOrCreate(
            ['user_id' => 1],
            [
                'preferences' => ['theme' => 'dark', 'notifications' => true],
                'features' => ['comments', 'likes'],
                'is_admin_flag' => 1,
                'last_login_at' => now(),
                'custom_setting_object' => ['key' => 'value']
            ]
        );

        echo "User Preferences (array): " . json_encode($settings->preferences) . " (Type: " . gettype($settings->preferences) . ")
";
        echo "First Feature (Collection): " . $settings->features->first() . " (Type: " . get_class($settings->features) . ")
";
        echo "Is Admin (boolean): " . ($settings->is_admin_flag ? 'Yes' : 'No') . " (Type: " . gettype($settings->is_admin_flag) . ")
";
        echo "Last Login At (Carbon instance): " . $settings->last_login_at->format('Y-m-d H:i:s') . " (Type: " . get_class($settings->last_login_at) . ")
";
        echo "Custom Setting Object (array from custom cast): " . json_encode($settings->custom_setting_object) . " (Type: " . gettype($settings->custom_setting_object) . ")
";

        // Update a setting
        $settings->preferences['notifications'] = false;
        $settings->features->push('sharing');
        $settings->is_admin_flag = false;
        $settings->save();

        echo "
Updated Preferences (notifications): " . json_encode($settings->preferences['notifications']) . "
";
        echo "Updated Features (Collection size): " . $settings->features->count() . "
";

        return "Attribute casting demonstrated. Check console/logs.";
    }
}
How it works: Attribute casting in Laravel Eloquent allows you to convert an attribute's raw database value to a different data type or object when you access it on your model. This is defined in the `$casts` property of your model. Common cast types include `array` (for JSON columns), `boolean`, `integer`, `float`, `datetime` (for Carbon instances), and `collection` (for `Illuminate\Support\Collection` instances). You can also create custom cast classes for more complex transformations, providing granular control over how attributes are stored and retrieved.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs