Laravel Tricks: Store money value as a integer using "Laravel Cast" method.

Laravel Tricks: Store money value as a integer using "Laravel Cast" method.

Table of contents

No heading

No headings in the article.

I was working on a Laravel project where I was storing money values as integers in the database. I am not using any decimal type for the table, just a simple integer. This is how I have done it.

To begin with, let's see an example: I am storing a product's pricing inside a database. The field will accept integers as input. Let's assume the product's pricing is 99.99, which will be stored as 9999 in the field (price x 100), but when we get the value, it will return "99.99" (price x 100). Now, the simplest and most effective method is to use the "cast" method. So I have created a cast using the artisan command.

php artian make:cast MoneyCast

Now we need to define 'set' and 'get' methods for this.

class MoneyCast implements CastsAttributes
{
    /**
     * Cast the given value.
     *
     * @param  array<string, mixed>  $attributes
     */
    public function get(Model $model, string $key, mixed $value, array $attributes): mixed
    {
        // return $value;
        return (float) ($value / 100);
    }

    /**
     * Prepare the given value for storage.
     *
     * @param  array<string, mixed>  $attributes
     */
    public function set(Model $model, string $key, mixed $value, array $attributes): mixed
    {
        // return $value;
        return (int) ($value * 100);
    }
}

Now that we have a money cast, we will define the field in which to use this cast. For this example, let's imagine that the price' inside the product needs this cast. Let's defy this.

// Import the cast first
// use App\Casts\MoneyCast;
protected $casts = [
        'price' => MoneyCast::class,
    ];

And there you have it. A simple Laravel Way to store pricing as an integer

Update:
I found this updated snippet on the Filament Docs site, apparently they also prefer integers to be stored inside databases.

//file: "app/Casts/MoneyCast.php"
public function get($model, string $key, $value, array $attributes): float
{
    // Transform the integer stored in the database into a float.
    return round(floatval($value) / 100, precision: 2);
}

public function set($model, string $key, $value, array $attributes): float
{
    // Transform the float into an integer for storage.
    return round(floatval($value) * 100);
}

Casting in filament docs link