@@ -12,11 +12,9 @@ module ClassMethods
12
12
def monetized_attributes
13
13
monetized_attributes = @monetized_attributes || { } . with_indifferent_access
14
14
15
- if superclass . respond_to? ( :monetized_attributes )
16
- monetized_attributes . merge ( superclass . monetized_attributes )
17
- else
18
- monetized_attributes
19
- end
15
+ return monetized_attributes unless superclass . respond_to? ( :monetized_attributes )
16
+
17
+ monetized_attributes . merge ( superclass . monetized_attributes )
20
18
end
21
19
22
20
def monetize ( *fields )
@@ -32,7 +30,7 @@ def monetize(*fields)
32
30
":with_currency or :with_model_currency" )
33
31
end
34
32
35
- name = options [ :as ] || options [ :target_name ] || nil
33
+ name = options [ :as ] || options [ :target_name ]
36
34
37
35
# Form target name for the money backed ActiveModel field:
38
36
# if a target name is provided then use it
@@ -46,34 +44,38 @@ def monetize(*fields)
46
44
if name == subunit_name
47
45
raise ArgumentError , "monetizable attribute name cannot be the same as options[:as] parameter"
48
46
end
49
-
50
- elsif subunit_name =~ /#{ MoneyRails ::Configuration . amount_column [ :postfix ] } $/
51
- name = subunit_name . sub ( /#{ MoneyRails ::Configuration . amount_column [ :postfix ] } $/ , "" )
52
47
else
53
- raise ArgumentError , "Unable to infer the name of the monetizable attribute for '#{ subunit_name } '. " \
54
- "Expected amount column postfix is '#{ MoneyRails ::Configuration . amount_column [ :postfix ] } '. " \
55
- "Use :as option to explicitly specify the name or change the amount column postfix in the initializer."
48
+ amount_column_postfix = MoneyRails ::Configuration . amount_column [ :postfix ]
49
+
50
+ if subunit_name =~ /#{ amount_column_postfix } $/
51
+ name = subunit_name . sub ( /#{ amount_column_postfix } $/ , "" )
52
+ else
53
+ raise ArgumentError , "Unable to infer the name of the monetizable attribute for '#{ subunit_name } '. " \
54
+ "Expected amount column postfix is '#{ amount_column_postfix } '. " \
55
+ "Use :as option to explicitly specify the name or change the amount column postfix in the initializer."
56
+ end
56
57
end
57
58
58
59
# Optional accessor to be run on an instance to detect currency
59
60
instance_currency_name = options [ :with_model_currency ] ||
60
- options [ :model_currency ] ||
61
- MoneyRails ::Configuration . currency_column [ :column_name ]
61
+ options [ :model_currency ] ||
62
+ MoneyRails ::Configuration . currency_column [ :column_name ]
62
63
63
64
# Infer currency column from name and postfix
64
- if !instance_currency_name && MoneyRails ::Configuration . currency_column [ :postfix ] . present?
65
- instance_currency_name = "#{ name } #{ MoneyRails ::Configuration . currency_column [ :postfix ] } "
66
- end
65
+ currency_column_postfix = MoneyRails ::Configuration . currency_column [ :postfix ]
67
66
68
- instance_currency_name = instance_currency_name && instance_currency_name . to_s
67
+ if instance_currency_name
68
+ instance_currency_name = instance_currency_name . to_s
69
+ elsif currency_column_postfix . present?
70
+ instance_currency_name = "#{ name } #{ currency_column_postfix } "
71
+ end
69
72
70
73
# This attribute allows per column currency values
71
74
# Overrides row and default currency
72
- field_currency_name = options [ :with_currency ] ||
73
- options [ :field_currency ] || nil
75
+ field_currency_name = options [ :with_currency ] || options [ :field_currency ]
74
76
75
77
# Create a reverse mapping of the monetized attributes
76
- track_monetized_attribute name , subunit_name
78
+ track_monetized_attribute ( name , subunit_name )
77
79
78
80
# Include numericality validations if needed.
79
81
# There are two validation options:
@@ -97,56 +99,54 @@ def monetize(*fields)
97
99
#
98
100
# To disable validation entirely, use :disable_validation, E.g:
99
101
# monetize :price_in_a_range_cents, disable_validation: true
100
- if ( validation_enabled = MoneyRails . include_validations && !options [ :disable_validation ] )
101
-
102
- # This is a validation for the subunit
103
- if ( subunit_numericality = options . fetch ( :subunit_numericality , true ) )
104
- validates subunit_name , {
105
- allow_nil : options [ :allow_nil ] ,
106
- numericality : subunit_numericality
107
- }
102
+ validation_enabled = MoneyRails . include_validations && !options [ :disable_validation ]
103
+
104
+ if validation_enabled
105
+ validate_subunit_numericality = options . fetch ( :subunit_numericality , true )
106
+ validate_numericality = options . fetch ( :numericality , true )
107
+
108
+ if validate_subunit_numericality
109
+ validates subunit_name , allow_nil : options [ :allow_nil ] ,
110
+ numericality : validate_subunit_numericality
108
111
end
109
112
110
113
# Allow only Money objects or Numeric values!
111
- if ( numericality = options . fetch ( :numericality , true ) )
112
- validates name . to_sym , {
113
- allow_nil : options [ :allow_nil ] ,
114
- 'money_rails/active_model/money' => numericality
115
- }
114
+ if validate_numericality
115
+ validates name . to_sym , allow_nil : options [ :allow_nil ] ,
116
+ 'money_rails/active_model/money' => validate_numericality
116
117
end
117
118
end
118
119
119
-
120
120
# Getter for monetized attribute
121
121
define_method name do |*args , **kwargs |
122
- read_monetized name , subunit_name , options , *args , **kwargs
122
+ read_monetized ( name , subunit_name , options , *args , **kwargs )
123
123
end
124
124
125
125
# Setter for monetized attribute
126
126
define_method "#{ name } =" do |value |
127
- write_monetized name , subunit_name , value , validation_enabled , instance_currency_name , options
127
+ write_monetized ( name , subunit_name , value , validation_enabled , instance_currency_name , options )
128
128
end
129
129
130
130
if validation_enabled
131
131
# Ensure that the before_type_cast value is cleared when setting
132
132
# the subunit value directly
133
133
define_method "#{ subunit_name } =" do |value |
134
- instance_variable_set "@#{ name } _money_before_type_cast" , nil
134
+ instance_variable_set ( "@#{ name } _money_before_type_cast" , nil )
135
135
write_attribute ( subunit_name , value )
136
136
end
137
137
end
138
138
139
139
# Currency getter
140
140
define_method "currency_for_#{ name } " do
141
- currency_for name , instance_currency_name , field_currency_name
141
+ currency_for ( name , instance_currency_name , field_currency_name )
142
142
end
143
143
144
144
attr_reader "#{ name } _money_before_type_cast"
145
145
146
146
# Hook to ensure the reset of before_type_cast attr
147
147
# TODO: think of a better way to avoid this
148
148
after_save do
149
- instance_variable_set "@#{ name } _money_before_type_cast" , nil
149
+ instance_variable_set ( "@#{ name } _money_before_type_cast" , nil )
150
150
end
151
151
end
152
152
end
@@ -185,12 +185,12 @@ def read_monetized(name, subunit_name, options = nil, *args, **kwargs)
185
185
kwargs = { }
186
186
end
187
187
188
- if kwargs . any?
189
- amount = public_send ( subunit_name , *args , **kwargs )
190
- else
191
- # Ruby 2.x does not allow empty kwargs
192
- amount = public_send ( subunit_name , *args )
193
- end
188
+ amount = if kwargs . any?
189
+ public_send ( subunit_name , *args , **kwargs )
190
+ else
191
+ # Ruby 2.x does not allow empty kwargs
192
+ public_send ( subunit_name , *args )
193
+ end
194
194
195
195
return if amount . nil? && options [ :allow_nil ]
196
196
# Get the currency object
@@ -218,7 +218,8 @@ def read_monetized(name, subunit_name, options = nil, *args, **kwargs)
218
218
end
219
219
220
220
if MoneyRails ::Configuration . preserve_user_input
221
- value_before_type_cast = instance_variable_get "@#{ name } _money_before_type_cast"
221
+ value_before_type_cast = instance_variable_get ( "@#{ name } _money_before_type_cast" )
222
+
222
223
if errors . has_key? ( name . to_sym )
223
224
result . define_singleton_method ( :to_s ) { value_before_type_cast }
224
225
result . define_singleton_method ( :format ) { |_ | value_before_type_cast }
@@ -230,23 +231,21 @@ def read_monetized(name, subunit_name, options = nil, *args, **kwargs)
230
231
231
232
def write_monetized ( name , subunit_name , value , validation_enabled , instance_currency_name , options )
232
233
# Keep before_type_cast value as a reference to original input
233
- instance_variable_set "@#{ name } _money_before_type_cast" , value
234
+ instance_variable_set ( "@#{ name } _money_before_type_cast" , value )
234
235
235
236
# Use nil or get a Money object
236
237
if options [ :allow_nil ] && value . blank?
237
238
money = nil
239
+ elsif value . is_a? ( Money )
240
+ money = value
238
241
else
239
- if value . is_a? ( Money )
240
- money = value
241
- else
242
- begin
243
- money = value . to_money ( public_send ( "currency_for_#{ name } " ) )
244
- rescue NoMethodError
245
- return nil
246
- rescue Money ::Currency ::UnknownCurrency , Monetize ::ParseError => e
247
- raise MoneyRails ::Error , e . message if MoneyRails . raise_error_on_money_parsing
248
- return nil
249
- end
242
+ begin
243
+ money = value . to_money ( public_send ( "currency_for_#{ name } " ) )
244
+ rescue NoMethodError
245
+ return nil
246
+ rescue Money ::Currency ::UnknownCurrency , Monetize ::ParseError => e
247
+ raise MoneyRails ::Error , e . message if MoneyRails . raise_error_on_money_parsing
248
+ return nil
250
249
end
251
250
end
252
251
@@ -273,26 +272,38 @@ def write_monetized(name, subunit_name, value, validation_enabled, instance_curr
273
272
public_send ( "#{ instance_currency_name } =" , money_currency . iso_code )
274
273
else
275
274
current_currency = public_send ( "currency_for_#{ name } " )
275
+
276
276
if current_currency != money_currency . id
277
- raise ReadOnlyCurrencyException . new ( "Can't change readonly currency '#{ current_currency } ' to '#{ money_currency } ' for field '#{ name } '" ) if MoneyRails . raise_error_on_money_parsing
277
+ if MoneyRails . raise_error_on_money_parsing
278
+ raise ReadOnlyCurrencyException ,
279
+ "Can't change readonly currency '#{ current_currency } ' to '#{ money_currency } ' for field '#{ name } '"
280
+ end
281
+
278
282
return nil
279
283
end
280
284
end
281
285
end
282
286
283
287
# Save and return the new Money object
284
- instance_variable_set "@#{ name } " , money
288
+ instance_variable_set ( "@#{ name } " , money )
285
289
end
286
290
287
291
def currency_for ( name , instance_currency_name , field_currency_name )
288
- if instance_currency_name . present? && respond_to? ( instance_currency_name ) &&
289
- Money ::Currency . find ( public_send ( instance_currency_name ) )
290
-
291
- Money ::Currency . find ( public_send ( instance_currency_name ) )
292
- elsif field_currency_name . respond_to? ( :call )
293
- Money ::Currency . find ( field_currency_name . call ( self ) )
294
- elsif field_currency_name
295
- Money ::Currency . find ( field_currency_name )
292
+ if instance_currency_name . present? && respond_to? ( instance_currency_name )
293
+ currency_name = public_send ( instance_currency_name )
294
+ currency = Money ::Currency . find ( currency_name )
295
+
296
+ return currency if currency
297
+ end
298
+
299
+ if field_currency_name
300
+ currency_name = if field_currency_name . respond_to? ( :call )
301
+ field_currency_name . call ( self )
302
+ else
303
+ field_currency_name
304
+ end
305
+
306
+ Money ::Currency . find ( currency_name )
296
307
elsif self . class . respond_to? ( :currency )
297
308
self . class . currency
298
309
else
0 commit comments