11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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/money-rails/active_record/monetizable.rb', line 11
def monetize(field, *args)
options = args.
subunit_name = field.to_s
if options[:field_currency] || options[:target_name] ||
options[:model_currency]
ActiveSupport::Deprecation.warn("You are using the old " \
"argument keys of monetize command! Instead use :as, " \
":with_currency or :with_model_currency")
end
instance_currency_name = options[:with_model_currency] ||
options[:model_currency] || "currency"
instance_currency_name = instance_currency_name.to_s
field_currency_name = options[:with_currency] ||
options[:field_currency] || nil
name = options[:as] || options[:target_name] || nil
if name
name = name.to_s
elsif subunit_name =~ /_cents$/
name = subunit_name.sub(/_cents$/, "")
else
name = [subunit_name, "money"].join("_")
end
@monetized_attributes ||= {}
@monetized_attributes[name.to_sym] = subunit_name
class << self
attr_reader :monetized_attributes
end unless respond_to? :monetized_attributes
if MoneyRails.include_validations
validates_numericality_of subunit_name, :allow_nil => options[:allow_nil]
validates name.to_sym, 'money_rails/active_model/money' => { :allow_nil => options[:allow_nil] }
end
define_method name do |*args|
amount = send(subunit_name, *args)
attr_currency = send("currency_for_#{name}")
memoized = instance_variable_get("@#{name}")
return memoized if memoized && memoized.cents == amount &&
memoized.currency == attr_currency
amount = Money.new(amount, attr_currency) unless amount.blank?
instance_variable_set "@#{name}", amount
end
define_method "#{name}=" do |value|
instance_variable_set "@#{name}_money_before_type_cast", value
if options[:allow_nil] && value.blank?
money = nil
else
begin
money = value.is_a?(Money) ? value : value.to_money(send("currency_for_#{name}"))
rescue NoMethodError
return nil
end
end
send("#{subunit_name}=", money.try(:cents))
send("#{instance_currency_name}=", money.try(:currency).try(:iso_code)) if self.respond_to?("#{instance_currency_name}=")
instance_variable_set "@#{name}", money
end
define_method "currency_for_#{name}" do
if self.respond_to?(instance_currency_name) && send(instance_currency_name).present?
Money::Currency.find(send(instance_currency_name))
elsif field_currency_name
Money::Currency.find(field_currency_name)
elsif self.class.respond_to?(:currency)
self.class.currency
else
Money.default_currency
end
end
define_method "#{name}_money_before_type_cast" do
instance_variable_get "@#{name}_money_before_type_cast"
end
after_validation do
instance_variable_set "@#{name}_money_before_type_cast", nil
end
end
|