@@ -12,11 +12,9 @@ module ClassMethods
1212 def monetized_attributes
1313 monetized_attributes = @monetized_attributes || { } . with_indifferent_access
1414
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 )
2018 end
2119
2220 def monetize ( *fields )
@@ -32,7 +30,7 @@ def monetize(*fields)
3230 ":with_currency or :with_model_currency" )
3331 end
3432
35- name = options [ :as ] || options [ :target_name ] || nil
33+ name = options [ :as ] || options [ :target_name ]
3634
3735 # Form target name for the money backed ActiveModel field:
3836 # if a target name is provided then use it
@@ -46,34 +44,38 @@ def monetize(*fields)
4644 if name == subunit_name
4745 raise ArgumentError , "monetizable attribute name cannot be the same as options[:as] parameter"
4846 end
49-
50- elsif subunit_name =~ /#{ MoneyRails ::Configuration . amount_column [ :postfix ] } $/
51- name = subunit_name . sub ( /#{ MoneyRails ::Configuration . amount_column [ :postfix ] } $/ , "" )
5247 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
5657 end
5758
5859 # Optional accessor to be run on an instance to detect currency
5960 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 ]
6263
6364 # 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 ]
6766
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
6972
7073 # This attribute allows per column currency values
7174 # 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 ]
7476
7577 # Create a reverse mapping of the monetized attributes
76- track_monetized_attribute name , subunit_name
78+ track_monetized_attribute ( name , subunit_name )
7779
7880 # Include numericality validations if needed.
7981 # There are two validation options:
@@ -97,56 +99,54 @@ def monetize(*fields)
9799 #
98100 # To disable validation entirely, use :disable_validation, E.g:
99101 # 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
108111 end
109112
110113 # 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
116117 end
117118 end
118119
119-
120120 # Getter for monetized attribute
121121 define_method name do |*args , **kwargs |
122- read_monetized name , subunit_name , options , *args , **kwargs
122+ read_monetized ( name , subunit_name , options , *args , **kwargs )
123123 end
124124
125125 # Setter for monetized attribute
126126 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 )
128128 end
129129
130130 if validation_enabled
131131 # Ensure that the before_type_cast value is cleared when setting
132132 # the subunit value directly
133133 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 )
135135 write_attribute ( subunit_name , value )
136136 end
137137 end
138138
139139 # Currency getter
140140 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 )
142142 end
143143
144144 attr_reader "#{ name } _money_before_type_cast"
145145
146146 # Hook to ensure the reset of before_type_cast attr
147147 # TODO: think of a better way to avoid this
148148 after_save do
149- instance_variable_set "@#{ name } _money_before_type_cast" , nil
149+ instance_variable_set ( "@#{ name } _money_before_type_cast" , nil )
150150 end
151151 end
152152 end
@@ -185,12 +185,12 @@ def read_monetized(name, subunit_name, options = nil, *args, **kwargs)
185185 kwargs = { }
186186 end
187187
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
194194
195195 return if amount . nil? && options [ :allow_nil ]
196196 # Get the currency object
@@ -218,7 +218,8 @@ def read_monetized(name, subunit_name, options = nil, *args, **kwargs)
218218 end
219219
220220 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+
222223 if errors . has_key? ( name . to_sym )
223224 result . define_singleton_method ( :to_s ) { value_before_type_cast }
224225 result . define_singleton_method ( :format ) { |_ | value_before_type_cast }
@@ -230,23 +231,21 @@ def read_monetized(name, subunit_name, options = nil, *args, **kwargs)
230231
231232 def write_monetized ( name , subunit_name , value , validation_enabled , instance_currency_name , options )
232233 # 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 )
234235
235236 # Use nil or get a Money object
236237 if options [ :allow_nil ] && value . blank?
237238 money = nil
239+ elsif value . is_a? ( Money )
240+ money = value
238241 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
250249 end
251250 end
252251
@@ -273,26 +272,38 @@ def write_monetized(name, subunit_name, value, validation_enabled, instance_curr
273272 public_send ( "#{ instance_currency_name } =" , money_currency . iso_code )
274273 else
275274 current_currency = public_send ( "currency_for_#{ name } " )
275+
276276 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+
278282 return nil
279283 end
280284 end
281285 end
282286
283287 # Save and return the new Money object
284- instance_variable_set "@#{ name } " , money
288+ instance_variable_set ( "@#{ name } " , money )
285289 end
286290
287291 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 )
296307 elsif self . class . respond_to? ( :currency )
297308 self . class . currency
298309 else
0 commit comments