money-rails 1.15.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -6
  3. data/LICENSE +1 -1
  4. data/README.md +121 -102
  5. data/config/locales/money.pt.yml +4 -0
  6. data/lib/money-rails/active_job/money_serializer.rb +19 -0
  7. data/lib/money-rails/active_record/monetizable.rb +17 -7
  8. data/lib/money-rails/configuration.rb +2 -2
  9. data/lib/money-rails/helpers/action_view_extension.rb +1 -1
  10. data/lib/money-rails/hooks.rb +11 -0
  11. data/lib/money-rails/version.rb +3 -1
  12. data/money-rails.gemspec +13 -26
  13. metadata +16 -225
  14. data/Rakefile +0 -84
  15. data/spec/active_record/migration_extensions/schema_statements_spec.rb +0 -101
  16. data/spec/active_record/migration_extensions/table_spec.rb +0 -104
  17. data/spec/active_record/monetizable_spec.rb +0 -1062
  18. data/spec/configuration_spec.rb +0 -147
  19. data/spec/dummy/README.rdoc +0 -261
  20. data/spec/dummy/Rakefile +0 -7
  21. data/spec/dummy/app/assets/config/manifest.js +0 -0
  22. data/spec/dummy/app/assets/javascripts/application.js +0 -15
  23. data/spec/dummy/app/assets/stylesheets/application.css +0 -13
  24. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  25. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  26. data/spec/dummy/app/models/dummy_product.rb +0 -8
  27. data/spec/dummy/app/models/priceable.rb +0 -8
  28. data/spec/dummy/app/models/product.rb +0 -59
  29. data/spec/dummy/app/models/service.rb +0 -5
  30. data/spec/dummy/app/models/transaction.rb +0 -13
  31. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  32. data/spec/dummy/config/application.rb +0 -66
  33. data/spec/dummy/config/boot.rb +0 -13
  34. data/spec/dummy/config/database.yml +0 -25
  35. data/spec/dummy/config/environment.rb +0 -5
  36. data/spec/dummy/config/environments/development.rb +0 -30
  37. data/spec/dummy/config/environments/production.rb +0 -69
  38. data/spec/dummy/config/environments/test.rb +0 -36
  39. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  40. data/spec/dummy/config/initializers/inflections.rb +0 -15
  41. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  42. data/spec/dummy/config/initializers/money.rb +0 -31
  43. data/spec/dummy/config/initializers/secret_token.rb +0 -7
  44. data/spec/dummy/config/initializers/session_store.rb +0 -8
  45. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  46. data/spec/dummy/config/locales/en-GB.yml +0 -11
  47. data/spec/dummy/config/locales/en-US.yml +0 -5
  48. data/spec/dummy/config/locales/en.yml +0 -5
  49. data/spec/dummy/config/locales/it.yml +0 -11
  50. data/spec/dummy/config/mongoid.yml +0 -29
  51. data/spec/dummy/config/routes.rb +0 -3
  52. data/spec/dummy/config.ru +0 -4
  53. data/spec/dummy/db/migrate/20120331190108_create_products.rb +0 -10
  54. data/spec/dummy/db/migrate/20120402080348_add_bonus_cents_to_product.rb +0 -6
  55. data/spec/dummy/db/migrate/20120524052716_create_services.rb +0 -10
  56. data/spec/dummy/db/migrate/20120528181002_create_transactions.rb +0 -11
  57. data/spec/dummy/db/migrate/20120528210103_create_dummy_products.rb +0 -10
  58. data/spec/dummy/db/migrate/20120607210247_add_column_that_allows_nil.rb +0 -5
  59. data/spec/dummy/db/migrate/20120712202655_add_sale_price_cents_to_product.rb +0 -7
  60. data/spec/dummy/db/migrate/20130124023419_add_price_in_a_range_cents_to_products.rb +0 -5
  61. data/spec/dummy/db/migrate/20140110194016_add_validates_method_amount_cents_to_products.rb +0 -5
  62. data/spec/dummy/db/migrate/20141005075025_add_aliased_attr_to_products.rb +0 -5
  63. data/spec/dummy/db/migrate/20150107061030_add_delivery_fee_cents_and_restock_fee_cents_to_product.rb +0 -6
  64. data/spec/dummy/db/migrate/20150126231442_add_reduced_price_to_products.rb +0 -6
  65. data/spec/dummy/db/migrate/20150213234410_add_special_price_to_products.rb +0 -5
  66. data/spec/dummy/db/migrate/20150217222612_add_lambda_price_to_products.rb +0 -5
  67. data/spec/dummy/db/migrate/20150303222230_add_skip_validation_price_cents_to_products.rb +0 -5
  68. data/spec/dummy/db/migrate/20151026220420_add_optional_amount_to_transactions.rb +0 -5
  69. data/spec/dummy/db/schema.rb +0 -59
  70. data/spec/dummy/db/structure.sql +0 -21
  71. data/spec/dummy/public/404.html +0 -26
  72. data/spec/dummy/public/422.html +0 -26
  73. data/spec/dummy/public/500.html +0 -25
  74. data/spec/dummy/public/favicon.ico +0 -0
  75. data/spec/dummy/script/rails +0 -6
  76. data/spec/helpers/action_view_extension_spec.rb +0 -189
  77. data/spec/helpers/form_helper_spec.rb +0 -19
  78. data/spec/money_spec.rb +0 -40
  79. data/spec/mongoid/mongoid_spec.rb +0 -130
  80. data/spec/mongoid/two_spec.rb +0 -80
  81. data/spec/spec_helper.rb +0 -23
  82. data/spec/support/database_cleaner.rb +0 -14
  83. data/spec/test_helpers_spec.rb +0 -72
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5bb5642fbc3d57d55b592911898fc1c0beeb8bb42bb21aeea89c89d1d3dc5464
4
- data.tar.gz: 8a5100169dea70dd4bbb8770a2273e59c6b99c555173025bfcc18fb4170fd7d0
3
+ metadata.gz: f19bdc8ef198214c817707194397d89dcd4a4582839c3665fa44a5058eaf33bd
4
+ data.tar.gz: 04e6523eb3ed34e9ab2c2596c35fea84a415b38c7e0a57fbc9412f4aa71c0877
5
5
  SHA512:
6
- metadata.gz: eb7961c60fab97af3a1e867ebcc192fcdc6468bb4239a18f60fb269014f898836051319db22b14c6b7c69b47287f6772be68d29db4e3be6a5d0366b895cea6b4
7
- data.tar.gz: 193580effbe3f55093e418f8ca6a0eea54bbfd6a46f07d0f8641a57d450564739716f69d18e743b839f785cc5d75513c234445a9378430f9bc943220598c51ae
6
+ metadata.gz: 6007152fd6ec545f080eb112e35a53e531bbaca69f635e630934c4f0662fa6f071fa62dabc42af779b6d1e68a5e419a4084f3da0006729768418e2a8f6637df8
7
+ data.tar.gz: 3450cf3305d2c5facc50e919ead251cacf95da4f414f35a924d96dee7c6970a23d197b411f18f4f839ac1e6583b2eee4c5409b7337ba443373c4b7c2808977c3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 2.0.0
6
+
7
+ - **Breaking change**: Requires `money` gem version ~> 7.0.
8
+ See the [Money 7.0 upgrading guide](https://github.com/RubyMoney/money/blob/main/UPGRADING-7.0.md)
9
+ - **Breaking change**: Requires `monetize` gem version ~> 7.0
10
+ - **Breaking change**: Drop support for Ruby < 3.1 and Rails < 6.1
11
+ - Allow monetizing methods with kwargs
12
+ - Fix `money_only_cents` for negative money
13
+ - Allow `nil` to be set as the default currency
14
+ - Portuguese translation for errors
15
+ - Skip subunit write for non-attributes in `read_monetized`
16
+
17
+ ## 1.15.0
18
+
19
+ - Bump money version to ~> 6.16
20
+ - Tweak to invalid currency message
21
+
3
22
  ## 1.14.1
4
23
 
5
24
  - Fix invalid_currency error definition
@@ -46,7 +65,7 @@
46
65
 
47
66
  - Bump money version to ~> 6.12.0
48
67
  - Bump monetize version to ~> 1.9.0
49
- - BREAKING CHANGE: Fix to rounding logic in this version from 1.11.0 can cause breaking changes for those relying on the incorrect behavior. Eee [the issue](https://github.com/RubyMoney/money-rails/issues/608) for details.
68
+ - BREAKING CHANGE: Fix to rounding logic in this version from 1.11.0 can cause breaking changes for those relying on the incorrect behavior. See [the issue](https://github.com/RubyMoney/money-rails/issues/608) for details.
50
69
 
51
70
  ## 1.11.0
52
71
 
@@ -84,7 +103,7 @@
84
103
  - Fix attribute order possibly affecting the value of monetized attribute
85
104
  - Add support for RailsAdmin (use :money type)
86
105
  - Raise error when gem was unable to infer monetized attribute name
87
- - Revert decimal mark and thousands separator addtion, since formatting should depend on country and locale, instead of currency
106
+ - Revert decimal mark and thousands separator addition, since formatting should depend on country and locale, instead of currency
88
107
 
89
108
  ## 1.6.1
90
109
 
@@ -148,8 +167,8 @@
148
167
  ## 1.1.0
149
168
 
150
169
  - Update dependencies to money 6.4.x and monetize 1.0.x.
151
- - Make subunit setter (e.g. `#price_cents=`) set the `before_type_cast...` va
152
- riable. (Fixes validation errors.)
170
+ - Make subunit setter (e.g. `#price_cents=`) set the `before_type_cast...`
171
+ variable. (Fixes validation errors.)
153
172
  - use HashWithIndifferentAccess instead of Hash for
154
173
  ActiveRecord::Base::monetized_attributes
155
174
  - Let the 'monetize' test helper work when testing against the model's class,
@@ -159,7 +178,7 @@
159
178
  - Upgrade specs to RSpec 3
160
179
  - Use #respond_to? instead of #try? when monetizing an aliased attribute.
161
180
  - Allow aliased attributes to be monetized
162
- - Fix compatability issue with Rails 4.2
181
+ - Fix compatibility issue with Rails 4.2
163
182
  - Allow empty string as thousands separator.
164
183
  - Allow using a lambda to set default_currency
165
184
 
@@ -292,4 +311,3 @@
292
311
  ## 0.0.1
293
312
 
294
313
  - Hello World
295
-
data/LICENSE CHANGED
@@ -1,7 +1,7 @@
1
1
  MIT License
2
2
 
3
3
  Copyright (c) 2012 Andreas Loupasakis
4
- Copyright (c) 2021 Shane Emmons
4
+ Copyright (c) 2025 Shane Emmons
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,15 +1,14 @@
1
1
  # RubyMoney - Money-Rails
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/money-rails.svg)](http://badge.fury.io/rb/money-rails)
4
- [![Build Status](https://secure.travis-ci.org/RubyMoney/money-rails.svg?branch=master)](http://travis-ci.org/RubyMoney/money-rails)
5
- [![Code Climate](https://codeclimate.com/github/RubyMoney/money-rails.svg)](https://codeclimate.com/github/RubyMoney/money-rails)
4
+ [![Ruby](https://github.com/RubyMoney/money-rails/actions/workflows/ruby.yml/badge.svg)](https://github.com/RubyMoney/money-rails/actions/workflows/ruby.yml)
6
5
  [![License](http://img.shields.io/:license-mit-green.svg?style=flat)](http://opensource.org/licenses/MIT)
7
6
 
8
7
  ## Introduction
9
8
 
10
9
  This library provides integration of the [money](http://github.com/Rubymoney/money) gem with Rails.
11
10
 
12
- Use 'monetize' to specify which fields you want to be backed by
11
+ Use `monetize` to specify which fields you want to be backed by
13
12
  Money objects and helpers provided by the [money](http://github.com/Rubymoney/money)
14
13
  gem.
15
14
 
@@ -20,26 +19,26 @@ welcome to contribute to the project.
20
19
 
21
20
  ## Installation
22
21
 
23
- Add this line to your application's Gemfile:
22
+ Add it to your applications Gemfile using:
24
23
 
25
- gem 'money-rails', '~>1.12'
26
-
27
- And then execute:
28
-
29
- $ bundle
24
+ ```sh
25
+ bundle add money-rails
26
+ ```
30
27
 
31
28
  Or install it yourself using:
32
29
 
33
- $ gem install money-rails
30
+ ```sh
31
+ $ gem install money-rails
32
+ ```
34
33
 
35
34
  You can also use the money configuration initializer:
36
35
 
37
- ```
38
- $ rails g money_rails:initializer
36
+ ```sh
37
+ $ bin/rails generate money_rails:initializer
39
38
  ```
40
39
 
41
40
  There, you can define the default currency value and set other
42
- configuration parameters for the rails app.
41
+ configuration parameters for the Rails app.
43
42
 
44
43
  Without Rails in rack-based applications, call during initialization:
45
44
 
@@ -58,47 +57,44 @@ For example, we create a Product model which has an integer column called
58
57
 
59
58
  ```ruby
60
59
  class Product < ActiveRecord::Base
61
-
62
60
  monetize :price_cents
63
-
64
61
  end
65
62
  ```
66
63
 
67
- Now each Product object will also have an attribute called ```price``` which
64
+ Now each Product object will also have an attribute called `price` which
68
65
  is a `Money` object, and can be used for money comparisons, conversions etc.
69
66
 
70
67
  In this case the name of the money attribute is created automagically by removing the
71
- ```_cents``` suffix from the column name.
68
+ `_cents` suffix from the column name.
72
69
 
73
- If you are using another db column name, or you prefer another name for the
74
- money attribute, then you can provide an ```as``` argument with a string
75
- value to the ```monetize``` macro:
70
+ If you are using another database column name, or you prefer another name for the
71
+ money attribute, then you can provide an `as` argument with a string value to the
72
+ `monetize` macro:
76
73
 
77
74
  ```ruby
78
75
  monetize :discount_subunit, as: "discount"
79
76
  ```
80
77
 
81
- Now the model objects will have a ```discount``` attribute which is a `Money`
82
- object, wrapping the value of the ```discount_subunit``` column with a Money
78
+ Now the model objects will have a `discount` attribute which is a `Money`
79
+ object, wrapping the value of the `discount_subunit` column with a Money
83
80
  instance.
84
81
 
85
82
  #### Migration helpers
86
83
 
87
- If you want to add a money field to a product model you can use the ```add_money``` helper. This
88
- helper can be customized inside a ```MoneyRails.configure``` block. You should customize the
89
- ```add_money``` helper to match the most common use case and utilize it across all migrations.
84
+ If you want to add a money field to a product model you can use the `add_monetize` helper.
85
+ This helper can be customized inside a `MoneyRails.configure` block. You should customize
86
+ the `add_monetize` helper to match the most common use case and utilize it across all
87
+ migrations.
90
88
 
91
89
  ```ruby
92
90
  class MonetizeProduct < ActiveRecord::Migration
93
91
  def change
94
- add_money :products, :price # Rails 3
95
- add_monetize :products, :price # Rails 4x and above
92
+ add_monetize :products, :price
96
93
 
97
94
  # OR
98
95
 
99
96
  change_table :products do |t|
100
- t.money :price # Rails 3
101
- t.monetize :price # Rails 4x and above
97
+ t.monetize :price
102
98
  end
103
99
  end
104
100
  end
@@ -109,28 +105,23 @@ Another example, where the currency column is not included:
109
105
  ```ruby
110
106
  class MonetizeItem < ActiveRecord::Migration
111
107
  def change
112
- add_money :items, :price, currency: { present: false }
108
+ add_monetize :items, :price, currency: { present: false }
113
109
  end
114
110
  end
115
111
  ```
116
112
 
117
- Notice. Default value of currency field, generated by migration's helper, is USD. To override these defaults, you need change default_currency in money initializer and run migrations.
118
-
119
- The ```add_money``` helper is reversible, so you can use it inside ```change```
120
- migrations. If you're writing separate ```up``` and ```down``` methods, you
121
- can use the ```remove_money``` helper.
122
-
123
- ##### Notice for Rails >= 4.2 and PG adapter
113
+ Notice: Default value of currency field, generated by migrations helper, is
114
+ USD. To override these defaults, you need change the `default_currency` in an
115
+ initializer and run migrations.
124
116
 
125
- Due to the addition of the `money` column type for PostgreSQL in Rails 4.2, you
126
- will need to use `add_monetize` instead of `add_money` column. If you're adding
127
- the column within a `create_table` block, use `t.monetize`, and use
128
- `remove_monetize` to remove the column.
117
+ The `add_monetize` helper is reversible, so you can use it inside `change`
118
+ migrations. If you’re writing separate `up` and `down` methods, you can use the
119
+ `remove_monetize` helper.
129
120
 
130
121
  #### Allow nil values
131
122
 
132
- If you want to allow nil and/or blank values to a specific
133
- monetized field, you can use the `:allow_nil` parameter:
123
+ If you want to allow `nil` and/or blank values to a specific monetized field,
124
+ you can use the `:allow_nil` parameter:
134
125
 
135
126
  ```ruby
136
127
  # in Product model
@@ -138,7 +129,10 @@ monetize :optional_price_cents, allow_nil: true
138
129
 
139
130
  # in Migration
140
131
  def change
141
- add_money :products, :optional_price, amount: { null: true, default: nil }
132
+ add_monetize :products,
133
+ :optional_price,
134
+ amount: { null: true, default: nil },
135
+ currency: { null: true, default: nil }
142
136
  end
143
137
 
144
138
  # now blank assignments are permitted
@@ -150,7 +144,8 @@ product.optional_price_cents # => nil
150
144
 
151
145
  #### Allow large numbers
152
146
 
153
- If you foresee that you will be saving large values (range is -2147483648 to +2147483647 for Postgres), increase your integer column limit to bigint:
147
+ If you foresee that you will be saving large values (range is -2147483648 to
148
+ +2147483647 for Postgres), increase your integer column limit to `bigint`:
154
149
 
155
150
  ```ruby
156
151
  def change
@@ -165,15 +160,17 @@ You can also pass along
165
160
  such as this:
166
161
 
167
162
  ```ruby
168
- monetize :price_in_a_range_cents, allow_nil: true,
163
+ monetize :price_in_a_range_cents,
164
+ allow_nil: true,
169
165
  numericality: {
170
166
  greater_than_or_equal_to: 0,
171
167
  less_than_or_equal_to: 10000
172
168
  }
173
169
  ```
174
170
 
175
- Or, if you prefer, you can skip validations entirely for the attribute. This is useful if chosen attributes
176
- are aggregate methods and you wish to avoid executing them on every record save.
171
+ Or, if you prefer, you can skip validations entirely for the attribute. This is
172
+ useful if chosen attributes are aggregate methods and you wish to avoid executing
173
+ them on every record save.
177
174
 
178
175
  ```ruby
179
176
  monetize :price_in_a_range_cents, disable_validation: true
@@ -186,6 +183,17 @@ to the validation you are willing to skip, like this:
186
183
  monetize :price_in_a_range_cents, numericality: false
187
184
  ```
188
185
 
186
+ And you can also use `subunit_numericality` for subunit:
187
+
188
+ ```ruby
189
+ monetize :price_in_a_range_cents,
190
+ allow_nil: true,
191
+ subunit_numericality: {
192
+ greater_than_or_equal_to: 0,
193
+ less_than_or_equal_to: 100_00
194
+ }
195
+ ```
196
+
189
197
  ### Mongoid 2.x and 3.x
190
198
 
191
199
  `Money` is available as a field type to supply during a field definition:
@@ -231,18 +239,17 @@ Method return values can be monetized in the same way attributes are monetized.
231
239
 
232
240
  ```ruby
233
241
  class Transaction < ActiveRecord::Base
234
-
235
242
  monetize :price_cents
236
243
  monetize :tax_cents
237
244
  monetize :total_cents
245
+
238
246
  def total_cents
239
- return price_cents + tax_cents
247
+ price_cents + tax_cents
240
248
  end
241
-
242
249
  end
243
250
  ```
244
251
 
245
- Now each Transaction object has a method called `total` which returns a `Money` object.
252
+ Now each `Transaction` object has a method called `total` which returns a `Money` object.
246
253
 
247
254
  ### Currencies
248
255
 
@@ -254,14 +261,12 @@ initializer of money-rails:
254
261
  ```ruby
255
262
  # config/initializers/money.rb
256
263
  MoneyRails.configure do |config|
257
-
258
264
  # set the default currency
259
265
  config.default_currency = :usd
260
-
261
266
  end
262
267
  ```
263
- For complete list of available currency: [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217)
264
268
 
269
+ For a complete list of available currencies: [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217)
265
270
 
266
271
  If you need to set the default currency on a per-request basis, such as in a
267
272
  multi-tenant application, you may use a lambda to lazy-load the default currency
@@ -270,65 +275,73 @@ from a field in a configuration model called `Tenant` in this example:
270
275
  ```ruby
271
276
  # config/initializers/money.rb
272
277
  MoneyRails.configure do |config|
273
-
274
278
  # set the default currency based on client configuration
275
279
  config.default_currency = -> { Tenant.current.default_currency }
276
280
  end
277
281
  ```
278
282
 
283
+ Be aware that this **does not work in Rails 7+**, as the lambda is evaluated
284
+ immediately, and therefore requires your model to be already loaded.
285
+ Workarounds include wrapping the initialization in
286
+ `ActiveSupport::Reloader.to_prepare`, or creating a function that rescues
287
+ unloaded constants with an initialization-time default, and running that in your lambda.
288
+
279
289
  In many cases this is not enough, so there are some other options to
280
290
  meet your needs.
281
291
 
282
292
  #### Model Currency
283
293
 
284
294
  You can override the global default currency within a specific ActiveRecord
285
- model using the ```register_currency``` macro:
295
+ model using the `register_currency` macro:
286
296
 
287
297
  ```ruby
288
298
  # app/models/product.rb
289
299
  class Product < ActiveRecord::Base
290
-
291
300
  # Use EUR as model level currency
292
301
  register_currency :eur
293
302
 
294
303
  monetize :discount_subunit, as: "discount"
295
304
  monetize :bonus_cents
296
-
297
305
  end
298
306
  ```
299
307
 
300
- Now ```product.discount``` and ```product.bonus``` will return a `Money`
301
- object using EUR as their currency, instead of the default USD.
308
+ Now `product.discount` and `product.bonus` will return a `Money` object using
309
+ EUR as their currency, instead of the default USD.
302
310
 
303
311
  (This is not available in Mongoid).
304
312
 
305
- #### Attribute Currency (:with_currency)
313
+ #### Attribute Currency (`:with_currency`)
306
314
 
307
- By passing the option ```:with_currency``` to the ```monetize``` macro call,
308
- with a currency code (symbol or string) or a callable object (object that responds to the method ```call```) that returns a currency code, as its value, you can define a currency in a more granular
309
- way. This will let you attach the given currency only to the specified monetized model
310
- attribute (allowing you to, for example, monetize different attributes of the same model with different currencies.).
315
+ By passing the option `:with_currency` to the `monetize` macro call,
316
+ with a currency code (symbol or string) or a callable object (object that responds
317
+ to the `call` method) that returns a currency code, as its value, you can define
318
+ a currency in a more granular way. This will let you attach the given currency
319
+ only to the specified monetized model attribute (allowing you to, for example,
320
+ monetize different attributes of the same model with different currencies).
311
321
 
312
- This allows you to override both the model level and the global
313
- default currencies:
322
+ This allows you to override both the model level and the global default
323
+ currencies:
314
324
 
315
325
  ```ruby
316
326
  # app/models/product.rb
317
327
  class Product < ActiveRecord::Base
318
-
319
328
  # Use EUR as the model level currency
320
329
  register_currency :eur
321
330
 
322
331
  monetize :discount_subunit, as: "discount"
323
332
  monetize :bonus_cents, with_currency: :gbp
324
-
325
333
  end
326
334
  ```
327
335
 
328
- In this case ```product.bonus``` will return a Money object with GBP as its
329
- currency, whereas ```product.discount.currency.to_s # => EUR ```
336
+ In this case `product.bonus` will return a Money object with GBP as its
337
+ currency, whereas `product.discount.currency.to_s # => EUR`
330
338
 
331
- As mentioned earlier you can use an object that responds to the method ```call``` and accepts the model instance as a parameter. That means you can use a ```Proc``` or ```lambda``` (we would recommend ```lambda``` over ```Proc``` because of their [different control flow characteristics](https://stackoverflow.com/questions/1740046/whats-the-difference-between-a-proc-and-a-lambda-in-ruby)) or even define a separate ```class``` with an instance or class method (maybe even a ```module```) to return the currency code:
339
+ As mentioned earlier you can use an object that responds to the method `call`
340
+ and accepts the model instance as a parameter. That means you can use a `Proc`
341
+ or `lambda` (we would recommend `lambda` over `Proc` because of their
342
+ [different control flow characteristics](https://stackoverflow.com/questions/1740046/whats-the-difference-between-a-proc-and-a-lambda-in-ruby))
343
+ or even define a separate `class` with an instance or class method (maybe even a
344
+ `module`) to return the currency code:
332
345
 
333
346
  ```ruby
334
347
  class DeliveryFee
@@ -343,9 +356,7 @@ module OptionalPrice
343
356
  end
344
357
  end
345
358
 
346
- # app/models/product.rb
347
359
  class Product < ActiveRecord::Base
348
-
349
360
  monetize :price_cents, with_currency: ->(_product) { :gbp }
350
361
  monetize :delivery_fee_cents, with_currency: DeliveryFee.new
351
362
  monetize :optional_price_cents, with_currency: OptionalPrice
@@ -356,9 +367,9 @@ end
356
367
 
357
368
  All the previous options do not require any extra model fields to hold
358
369
  the currency values. If the currency of a field will vary from
359
- one model instance to another, then you should add a column called ```currency```
360
- to your database table and pass the option ```with_model_currency```
361
- to the ```monetize``` macro.
370
+ one model instance to another, then you should add a column called `currency`
371
+ to your database table and pass the option `with_model_currency`
372
+ to the `monetize` macro.
362
373
 
363
374
  money-rails will use this knowledge to override the model level and global
364
375
  default values. Non-nil instance currency values also override attribute
@@ -366,7 +377,6 @@ currency values, so they have the highest precedence.
366
377
 
367
378
  ```ruby
368
379
  class Transaction < ActiveRecord::Base
369
-
370
380
  # This model has a separate currency column
371
381
  attr_accessible :amount_cents, :currency, :tax_cents
372
382
 
@@ -375,7 +385,6 @@ class Transaction < ActiveRecord::Base
375
385
 
376
386
  monetize :amount_cents, with_model_currency: :currency
377
387
  monetize :tax_cents, with_model_currency: :currency
378
-
379
388
  end
380
389
 
381
390
  # Now instantiating with a specific currency overrides
@@ -386,11 +395,10 @@ t.amount == Money.new(2500, "CAD") # true
386
395
 
387
396
  ### Configuration parameters
388
397
 
389
- You can handle a bunch of configuration params through ```money.rb``` initializer:
398
+ You can handle a bunch of configuration params through `money.rb` initializer:
390
399
 
391
400
  ```ruby
392
401
  MoneyRails.configure do |config|
393
-
394
402
  # To set the default currency
395
403
  #
396
404
  # config.default_currency = :usd
@@ -471,25 +479,32 @@ MoneyRails.configure do |config|
471
479
  # symbol: nil,
472
480
  # sign_before_symbol: nil
473
481
  # }
482
+
483
+ # Set whether an error should be raised when parsing money values
484
+ # This includes assigning to a monetized field with the wrong currency
485
+ # Default value is false
486
+ #
487
+ # config.raise_error_on_money_parsing = true
474
488
  end
475
489
  ```
476
490
 
477
- * ```default_currency```: Set the default (application wide) currency (USD is the default)
478
- * ```include_validations```: Permit the inclusion of a ```validates_numericality_of```
491
+ * `default_currency`: Set the default (application wide) currency (USD is the default)
492
+ * `include_validations`: Permit the inclusion of a `validates_numericality_of`
479
493
  validation for each monetized field (the default is true)
480
- * ```register_currency```: Register one custom currency. This option can be
494
+ * `register_currency`: Register one custom currency. This option can be
481
495
  used more than once to set more custom currencies. The value should be
482
- a hash of all the necessary key/value pairs (important keys: ```:priority```, ```:iso_code```,
483
- ```:name```, ```:symbol```, ```:symbol_first```, ```:subunit```, ```:subunit_to_unit```,
484
- ```:thousands_separator```, ```:decimal_mark```).
485
- * ```add_rate```: Provide custom exchange rate for currencies in one direction
486
- only! This rate is added to the attached bank object.
487
- * ```default_bank```: The default bank object holding exchange rates etc.
496
+ a hash of all the necessary key/value pairs (important keys: `:priority`, `:iso_code`,
497
+ `:name`, `:symbol`, `:symbol_first`, `:subunit`, `:subunit_to_unit`,
498
+ `:thousands_separator`, `:decimal_mark`).
499
+ * `add_rate`: Provide custom exchange rate for currencies in one direction only! This
500
+ rate is added to the attached bank object.
501
+ * `default_bank`: The default bank object holding exchange rates etc.
488
502
  (https://github.com/RubyMoney/money#currency-exchange)
489
- * ```default_format```: Force `Money#format` to use these options for formatting.
490
- * ```amount_column```: Provide values for the amount column (holding the fractional part of a money object).
491
- * ```currency_column```: Provide default values or even disable (`present: false`) the currency column.
492
- * ```rounding_mode```: Set Money.rounding_mode to one of the BigDecimal constants
503
+ * `default_format`: Force `Money#format` to use these options for formatting.
504
+ * `amount_column`: Provide values for the amount column (holding the fractional part of a money object).
505
+ * `currency_column`: Provide default values or even disable (`present: false`) the currency column.
506
+ * `rounding_mode`: Set `Money.rounding_mode` to one of the BigDecimal constants.
507
+ * `raise_error_on_money_parsing`: Set whether errors should be raised when parsing money values
493
508
 
494
509
  ### Helpers
495
510
 
@@ -504,7 +519,7 @@ _For examples below, `@money_object == <Money fractional:650 currency:USD>`_
504
519
  | `money_without_cents_and_with_symbol @money_object` | $6 |
505
520
  | `money_only_cents @money_object` | 50 |
506
521
 
507
- #### `no_cents_if_whole`
522
+ #### `no_cents_if_whole` configuration param
508
523
 
509
524
  `humanized_money` and `humanized_money_with_symbol` will not render the cents part if it contains only zeros, unless `config.no_cents_if_whole` is set to `false` in the `money.rb` configuration (default: true).
510
525
  Note that the `config.default_format` will be overwritten by `config.no_cents_if_whole`.
@@ -513,23 +528,26 @@ So `humanized_money` will ignore `config.default_format = { no_cents_if_whole: f
513
528
  ### Testing
514
529
 
515
530
  If you use Rspec there is a test helper implementation.
516
- Just write `require "money-rails/test_helpers"` in spec_helper.rb.
531
+ Just write `require "money-rails/test_helpers"` in `spec_helper.rb`.
517
532
 
518
- * the `monetize` matcher
533
+ #### The `monetize` matcher
519
534
 
520
535
  ```ruby
521
536
  is_expected.to monetize(:price)
522
537
  ```
538
+
523
539
  This will ensure that a column called `price_cents` is being monetized.
524
540
 
525
541
  ```ruby
526
542
  is_expected.to monetize(:price).allow_nil
527
543
  ```
544
+
528
545
  By using `allow_nil` you can specify money attributes that accept nil values.
529
546
 
530
547
  ```ruby
531
548
  is_expected.to monetize(:price).as(:discount_value)
532
549
  ```
550
+
533
551
  By using `as` chain you can specify the exact name to which a monetized
534
552
  column is being mapped.
535
553
 
@@ -552,14 +570,15 @@ For examples on using the test_helpers look at
552
570
 
553
571
  ## Supported ORMs/ODMs
554
572
 
555
- * ActiveRecord (>= 3.x)
573
+ * ActiveRecord (>= 6.1)
556
574
  * Mongoid (>= 2.x)
557
575
 
558
576
  ## Supported Ruby interpreters
559
577
 
560
- * MRI Ruby >= 1.9.2
578
+ * MRI Ruby >= 3.0
561
579
 
562
- You can see a full list of the currently supported interpreters in [travis.yml](http://github.com/RubyMoney/money-rails/blob/master/.travis.yml)
580
+ You can see a full list of the currently supported interpreters in
581
+ [ruby.yml](https://github.com/RubyMoney/money-rails/blob/main/.github/workflows/ruby.yml)
563
582
 
564
583
  ## Contributing
565
584
 
@@ -587,4 +606,4 @@ If you are testing against mongoid, make sure to have the mongod process running
587
606
 
588
607
  ## License
589
608
 
590
- MIT License. Copyright 2021 RubyMoney.
609
+ [MIT License](https://github.com/RubyMoney/money-rails/blob/main/LICENSE). Copyright 2023 RubyMoney.
@@ -0,0 +1,4 @@
1
+ pt:
2
+ errors:
3
+ messages:
4
+ invalid_currency: tem um formato inválido (deve ser '100', '5%{decimal}24', ou '123%{thousands}456%{decimal}78'). Recebido %{currency}
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MoneyRails
4
+ module ActiveJob
5
+ class MoneySerializer < ::ActiveJob::Serializers::ObjectSerializer
6
+ def serialize?(argument)
7
+ argument.is_a?(Money)
8
+ end
9
+
10
+ def serialize(money)
11
+ super("cents" => money.cents, "currency" => money.currency.to_s)
12
+ end
13
+
14
+ def deserialize(hash)
15
+ Money.new(hash["cents"], hash["currency"])
16
+ end
17
+ end
18
+ end
19
+ end
@@ -10,7 +10,7 @@ module MoneyRails
10
10
 
11
11
  module ClassMethods
12
12
  def monetized_attributes
13
- monetized_attributes = @monetized_attributes || {}
13
+ monetized_attributes = @monetized_attributes || {}.with_indifferent_access
14
14
 
15
15
  if superclass.respond_to?(:monetized_attributes)
16
16
  monetized_attributes.merge(superclass.monetized_attributes)
@@ -118,8 +118,8 @@ module MoneyRails
118
118
 
119
119
 
120
120
  # Getter for monetized attribute
121
- define_method name do |*args|
122
- read_monetized name, subunit_name, options, *args
121
+ define_method name do |*args, **kwargs|
122
+ read_monetized name, subunit_name, options, *args, **kwargs
123
123
  end
124
124
 
125
125
  # Setter for monetized attribute
@@ -178,9 +178,19 @@ module MoneyRails
178
178
  end
179
179
  end
180
180
 
181
- def read_monetized(name, subunit_name, options = {}, *args)
182
- # Get the cents
183
- amount = public_send(subunit_name, *args)
181
+ def read_monetized(name, subunit_name, options = nil, *args, **kwargs)
182
+ # Ruby 2.x compatibility
183
+ if options.nil?
184
+ options = kwargs
185
+ kwargs = {}
186
+ end
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
184
194
 
185
195
  return if amount.nil? && options[:allow_nil]
186
196
  # Get the currency object
@@ -195,7 +205,7 @@ module MoneyRails
195
205
  result = memoized
196
206
  else
197
207
  memoized_amount = memoized.amount.to_money(attr_currency)
198
- write_attribute subunit_name, memoized_amount.cents
208
+ write_attribute subunit_name, memoized_amount.cents if has_attribute? subunit_name
199
209
  # Cache the value (it may be nil)
200
210
  result = instance_variable_set("@#{name}", memoized_amount)
201
211
  end