Module: Sequel::Plugins::MoneyFields

Defined in:
lib/sequel/plugins/money_fields.rb

Overview

Plugin for adding money fields to a model.

Example

Define a model with money values:

class ACME::Property < Sequel::Model(:properties)

    plugin :money_fields, :rent

And in the schema:

create_table( :properties ) do
    primary_key :id
    bigint :rent_cents, null: false
    text :rent_currency, null: false, default: 'USD'
end

And used as follows:

property = ACME::Property.new(rent: Monetize.parse('$5'))
property.rent_cents # 500
property.rent # Money object presenting 5 USD

Each money field you declare requires two columns: an integer(ish) column that will store the fractional amount called “#field_cents”, and a text(ish) column for storing the currency name called “#field_currency”.

The plugin generates methods for getting and setting each field. The setter automatically parses the input using the ‘monetize’ gem into a Money object, and the getter creates a new Money object from the two columns and returns it.

If you don’t give at least one column to the plugin declaration, the field will be assumed to be called ‘money’.

See the docs for Money and Monetize for details on what you can do with the Money objects these fields use.

Constant Summary collapse

VERSION =
"0.1.0"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.configure(model, *args) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/sequel/plugins/money_fields.rb', line 53

def self.configure(model, *args)
  args << :money if args.empty?

  args.flatten.each do |field|
    reader = self.make_money_reader(field)
    writer = self.make_money_writer(field)

    model.send(:define_method, field.to_s, reader)
    model.send(:define_method, "#{field}=", writer)
  end
end

.make_money_reader(field) ⇒ Object

Return a Proc that can serve as the method body for the Money amount reader for the given field.



67
68
69
70
71
72
73
74
# File 'lib/sequel/plugins/money_fields.rb', line 67

def self.make_money_reader(field)
  cents_column = "#{field}_cents".to_sym
  currency_column = "#{field}_currency".to_sym

  return lambda do
    Money.new(self[cents_column], self[currency_column])
  end
end

.make_money_writer(field) ⇒ Object

Return a Proc that can serve as the method body for the Money amount writer for the given field.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/sequel/plugins/money_fields.rb', line 78

def self.make_money_writer(field)
  cents_column = "#{field}_cents".to_sym
  currency_column = "#{field}_currency".to_sym

  return lambda do |value|
    if value.respond_to?(:cents) && value.respond_to?(:currency)
      money = Money.new(value.cents, value.currency)
    else
      begin
        cents = value[:cents] || value["cents"]
        cur = value[:currency] || value["currency"]
        money = Money.new(cents, cur)
      rescue TypeError, NoMethodError
        money = Monetize.parse!(value)
      end
    end
    self[cents_column] = money.cents.to_i
    self[currency_column] = money.currency
  end
end

Instance Method Details

#singleton_attr_accessor(*symbols) ⇒ Object

Creates readers and writers that allow assignment to the attributes of the singleton of the declaring object that correspond to the specified symbols.



102
103
104
105
106
# File 'lib/sequel/plugins/money_fields.rb', line 102

def singleton_attr_accessor(*symbols)
  symbols.each do |sym|
    singleton_class.__send__(:attr_accessor, sym)
  end
end