Module: Plutonium::Models::HasCents::ClassMethods

Defined in:
lib/plutonium/models/has_cents.rb

Instance Method Summary collapse

Instance Method Details

#has_cents(cents_name, name: nil, rate: 100, suffix: "amount") ⇒ Object

super(*args, options, &block) end Defines getter and setter methods for a monetary value stored as cents, and ensures validations are applied to both cents and decimal attributes.

Examples:

Standard currency (dollars and cents)

has_cents :price_cents

Custom rate for a different currency division

has_cents :amount_cents, name: :cost, rate: 1000

Whole number storage without decimal places

has_cents :quantity_cents, name: :quantity, rate: 1

Using custom suffix

has_cents :total_cents, suffix: "value"

Parameters:

  • cents_name (Symbol)

    The name of the attribute storing the cents value.

  • name (Symbol, nil) (defaults to: nil)

    The name for the generated methods. If nil, it’s derived from cents_name.

  • rate (Integer) (defaults to: 100)

    The conversion rate from the decimal value to cents (default: 100). This represents how many cents are in one unit of the decimal value. For example:

    • rate: 100 for dollars/cents (1 dollar = 100 cents)

    • rate: 1000 for dollars/mils (1 dollar = 1000 mils)

    • rate: 1 for a whole number representation

  • suffix (String) (defaults to: "amount")

    The suffix to append to the cents_name if name is not provided (default: “amount”).



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/plutonium/models/has_cents.rb', line 124

def has_cents(cents_name, name: nil, rate: 100, suffix: "amount")
  cents_name = cents_name.to_sym
  name ||= cents_name.to_s.gsub(/_cents$/, "")
  name = name.to_sym
  name = (name == cents_name) ? :"#{cents_name}_#{suffix}" : name

  self.has_cents_attributes = has_cents_attributes.merge(
    cents_name => {name: name, rate: rate}
  )

  class_eval "    # Getter method for the decimal representation of the cents value.\n    #\n    # @return [BigDecimal, nil] The decimal value or nil if cents_name is not present.\n    def \#{name}\n      \#{cents_name}.to_d / \#{rate} if \#{cents_name}.present?\n    end\n\n    # Setter method for the decimal representation of the cents value.\n    #\n    # @param value [Numeric, nil] The decimal value to be set.\n    def \#{name}=(value)\n      self.\#{cents_name} = begin\n        (BigDecimal(value.to_s) * \#{rate}).to_i if value.present?\n      rescue ArgumentError\n        nil\n      end\n    end\n\n    # Mark decimal field as invalid if cents field is not valid\n    after_validation do\n      next unless errors[\#{cents_name.inspect}].present?\n\n      errors.add(\#{name.inspect}, :invalid)\n    end\n  RUBY\nend\n", __FILE__, __LINE__ + 1

#has_cents_attribute?(attribute) ⇒ Boolean

Checks if a given attribute is defined with has_cents

Parameters:

  • attribute (Symbol)

    The attribute to check

Returns:

  • (Boolean)

    true if the attribute is defined with has_cents, false otherwise



166
167
168
# File 'lib/plutonium/models/has_cents.rb', line 166

def has_cents_attribute?(attribute)
  has_cents_attributes.key?(attribute.to_sym)
end