How to store prices efficiently in Laravel Eloquent ?

ยท 375 words ยท 2 minute read

We can store prices efficiently in Laravel Eloquent by focusing on avoiding floating-point issues and optimizing storage. The appraoch is storing price as integer. Here is how.

How to store prices as integer ? ๐Ÿ”—

  • Define an integer column in your database table to store the price in the smallest denomination of your currency. For example, for USD, store the price in cents (e.g., $10.50 becomes 1050).
  • Use a mutator in your Eloquent model to handle price setting. The mutator multiplies the user-provided decimal value by the conversion factor (e.g., 100 for cents).
  • Define an accessor in your model to format the price for display. The accessor divides the stored integer value by the conversion factor and formats it as a decimal string (e.g., with currency symbol and commas).

Benefits of storing price as integer ๐Ÿ”—

  • Storage efficiency: Integers use less space compared to decimals.
  • Accuracy: Avoids rounding errors inherent in floating-point numbers.
  • Speed: Calculations with integers are faster.

Implementation of storing prices as integers ๐Ÿ”—

In your model, add the price column to the $fillables.

class Product extends Model
{
    protected $fillable = ['price'];
}

Add a mutator (a function) that convert decimal into integer before storing it into the database.

class Product extends Model
{
    // store 'int' instead of 'double' in db for performance
    public function setPriceAttribute($value)
    {
        // 5.50 USD (UI) -> 550 Cents (db)
        $this->attributes['price'] = $value * 100;
    }
}

Add an accessor (a function) that converts integer into decimal before accessing the price value.

class Product extends Model
{
    public function getPriceAttribute()
    {
        // 550 cents (db) -> 5.50 USD (UI)
        return number_format($this->attributes["price"] / 100, 2);
    }
}

But if you will use the price in further calculation, use this accessor (get function) instead.

class Product extends Model
{
    public function getPriceAttribute()
    {
        // 550 cents (db) -> 5.50 USD (UI)
        return floatval(number_format($this->attributes["price"] / 100, 2));
    }
}

because floatval() ensures that the returned value is a floating-point number.

I hope this post helps you. If you know a person who can benefit from this information, send them a link of this post. If you want to get notified about new posts, follow me on YouTube , Twitter (x) , LinkedIn , Facebook , Telegram and GitHub .

Share: