Module: Plutonium::Models::HasCents

Extended by:
ActiveSupport::Concern
Included in:
Resource::Record
Defined in:
lib/plutonium/models/has_cents.rb

Overview

Note:

This module automatically handles validation propagation. If a validation error is applied to the cents attribute, the decimal attribute will be marked as invalid.

Note:

The module uses BigDecimal for internal calculations to ensure precision in monetary operations.

HasCents module provides functionality to handle monetary values stored as cents and expose them as decimal values. It also ensures that validations applied to the cents attribute are inherited by the decimal attribute.

Examples:

Usage

class Product < ApplicationRecord
  include Plutonium::Models::HasCents

  has_cents :price_cents
  has_cents :cost_cents, name: :wholesale_price, rate: 1000
  has_cents :quantity_cents, name: :quantity, rate: 1
  has_cents :total_cents, suffix: "value"

  validates :price_cents, numericality: { greater_than_or_equal_to: 0 }
end

Basic Usage

product = Product.new(price: 10.99)

product.price_cents #=> 1099
product.price #=> 10.99

product.wholesale_price = 5.5
product.cost_cents #=> 5500

product.quantity = 3
product.quantity_cents #=> 3

Truncation

product.price = 10.991
product.price_cents #=> 1099

product.price = 10.995
product.price_cents #=> 1099

product.price = 10.999
product.price_cents #=> 1099

product.total_value = 100.50
product.total_cents #=> 10050

Validation Inheritance

product = Product.new(price: -10.99)
product.valid? #=> false
product.errors[:price_cents] #=> ["must be greater than or equal to 0"]
product.errors[:price] #=> ["is invalid"]

Reflection

Product.has_cents_attributes
#=> {
#     price_cents: { name: :price, rate: 100 },
#     cost_cents: { name: :wholesale_price, rate: 1000 },
#     quantity_cents: { name: :quantity, rate: 1 },
#     total_cents: { name: :total_value, rate: 100 }
#   }

Product.has_cents_attribute?(:price_cents) #=> true
Product.has_cents_attribute?(:name) #=> false
Product.has_cents_attributes[:cost_cents] #=> {name: :wholesale_price, rate: 1000}

See Also:

Defined Under Namespace

Modules: ClassMethods