Module: FixedPointField::ClassMethods

Defined in:
lib/fixed_point_field.rb

Instance Method Summary collapse

Instance Method Details

#fixed_point_field(*fields) ⇒ Object

Calling this in an active record class will make getters / setters available for in integer field that return / accept values that are floating point. It will convert them to integer values by up-scaling the number by a certain number of decimal places. This is most useful for working with money, when the values can be stored as cents, but will most often be working with dollars, which always has two places after the decimal reserved for cents.

Takes any number of field names to be converted, and an optional hash as the last argument. The hash can have keys of :width, which is the number of places beyond the decimal to use (default 2), and :base, which is the number system to use (default 10 [decimal]).

This for a field named my_field, this will generate the methods

* my_field - returns the value as a float
* my_field_fixed - returns the value as it is stored (Fixnum)
* my_field= - takes a floating point number and scales it appropriately
* my_field_fixed= - direct setter for fixed point number


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/fixed_point_field.rb', line 93

def fixed_point_field *fields
  opts = (fields.pop if fields.last.is_a?(Hash)) || {}
  opts[:width] ||= 2
  opts[:base] ||= 10
  fields.each do |field|
    read_fixed_method = "#{field}_fixed"
    read_float_method = "#{field}"
    set_float_method = "#{field}="
    set_fixed_method = "#{field}_fixed="

    define_method(read_fixed_method) do
      read_fixed_point(field)
    end

    define_method(read_float_method) do
      read_floating_point(field, opts[:width], opts[:base])
    end

    define_method(set_float_method) do |value|
      set_floating_point(field, value, opts[:width], opts[:base])
    end

    define_method(set_fixed_method) do |value|
      set_fixed_point(field, value)
    end

  end
end