minting-rails 0.3.3 → 0.4.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3bd3a7589733a495cc181ffa6ab521e5c8090c03cbc3ab5e94b5cd2f75053a44
4
- data.tar.gz: 3dcaaa12c7f389d07e29f4ffe7c6636c3370e78a11f366b4ffef9f92539ab026
3
+ metadata.gz: 5808a2bc3360d2922f6daafe1b3fb76fd22b7e42e55f953c9a710b6403b4d85d
4
+ data.tar.gz: 3a8f0681a8ec28df623c663a2dcfac34460efab3fa022183b6b69fb3beccf2de
5
5
  SHA512:
6
- metadata.gz: 4d14f5bf882de78babfc661320fa08a9a182addcd429bebcc1df1c604a09778d637dd34000cb386816e6c3e089018563696dbcedbfcd1bffc38cd8d9832d1914
7
- data.tar.gz: cbef220622baba1a8fc0eedce69b6854c2786d347e0b7d487913654ab6221849dff57ce6e7ca8f25fb3ba3e1a433536fcc829afc68fd56227c9dadb6ed2e4ac7
6
+ metadata.gz: 99b0a1f2b1a2f66687c925cf747af3ec24af0b30847f5ac498a443e28bdc4b8e4a4b66b96211340b73d89a188a2a3bbb60363abb2e3af3a74b911077824e929f
7
+ data.tar.gz: 591a1dc0d5d7db7cb016294dd0aeb1e235468e95153653348bc8a2e937830369baa9875599cbfa4864beed2cad20a41bd2ba4427e9a196cba595c2034eb4e258
data/README.md CHANGED
@@ -1,65 +1,266 @@
1
1
  # Minting::Rails
2
2
 
3
- Minting::Rails is a gem that provides money attributes to ActiveRecord models. It integrates the [Minting](https://github.com/gferraz/minting) library into your Rails application.
3
+ Minting::Rails brings [Minting](https://github.com/gferraz/minting) money objects to Active Record models.
4
+
5
+ It adds a `money_attribute` model helper, registers a `:mint_money` Active Record type, and includes small convenience methods such as `12.to_money(:USD)`, `12.dollars`, and `'12.00'.mint(:BRL)`.
6
+
7
+ ## What it does
8
+
9
+ - Stores and reads model attributes as `Mint::Money` objects.
10
+ - Supports composed money attributes backed by amount and currency columns.
11
+ - Normalizes numeric, string, and `Mint::Money` assignments.
12
+ - Validates currencies against the currencies enabled in Minting.
13
+
14
+ ## Requirements
15
+
16
+ - Ruby 3.3 or newer.
17
+ - Rails 7.1.3.2 or newer.
18
+ - Minting 1.0.0 or newer.
4
19
 
5
20
  ## Installation
6
21
 
7
- Add this line to your application's Gemfile:
22
+ Add the gem to your Rails application's `Gemfile`:
8
23
 
9
24
  ```ruby
10
25
  gem 'minting-rails'
11
26
  ```
12
27
 
13
- And then execute:
28
+ Install it:
14
29
 
15
- ```bash
16
- bundle
30
+ ```sh
31
+ bundle install
32
+ ```
33
+
34
+ Generate the initializer:
35
+
36
+ ```sh
37
+ bin/rails g mint:initializer
17
38
  ```
18
39
 
19
40
  ## Configuration
20
41
 
21
- After intalling generate Minting configuration initializer:
42
+ Configure Minting in `config/initializers/minting.rb`:
22
43
 
23
- ```sh
24
- rails g mint:initializer
44
+ ```ruby
45
+ Mint.configure do |config|
46
+ config.enabled_currencies = :all
47
+ config.default_currency = 'USD'
48
+ end
25
49
  ```
26
50
 
27
- You can configure the default currency for your application by adding the following line to your config/initializers/minting.rb:
51
+ You can limit the currencies that may be used:
28
52
 
29
53
  ```ruby
30
- Minting.configure do |config|
31
- config.default_currency = :usd
54
+ Mint.configure do |config|
55
+ config.enabled_currencies = %w[USD EUR BRL]
56
+ config.default_currency = 'USD'
32
57
  end
33
58
  ```
34
59
 
60
+ You can also register custom currencies before enabling or using them:
61
+
62
+ ```ruby
63
+ Mint.configure do |config|
64
+ config.added_currencies = [
65
+ { currency: 'CRC', subunit: 2, symbol: 'CRC' },
66
+ { currency: 'NGN', subunit: 2, symbol: 'NGN' }
67
+ ]
68
+
69
+ config.enabled_currencies = :all
70
+ config.default_currency = 'CRC'
71
+ end
72
+ ```
73
+
74
+ The default currency must be registered and included in `enabled_currencies`.
75
+
35
76
  ## Usage
36
77
 
37
- To use Minting::Rails, you add the money_attribute method to your ActiveRecord models. For example:
78
+ Declare money attributes in your Active Record models with `money_attribute`.
79
+
80
+ ### Single-column fixed currency
81
+
82
+ Use this when a column always stores one currency, such as a `price` column that is always USD.
83
+
84
+ Migration:
85
+
86
+ ```ruby
87
+ class CreateProducts < ActiveRecord::Migration[7.1]
88
+ def change
89
+ create_table :products do |t|
90
+ t.decimal :price
91
+ t.decimal :discount
92
+
93
+ t.timestamps
94
+ end
95
+ end
96
+ end
97
+ ```
98
+
99
+ Model:
38
100
 
39
101
  ```ruby
40
- class SimpleOffer < ApplicationRecord
102
+ class Product < ApplicationRecord
41
103
  money_attribute :price, currency: 'USD'
42
104
  money_attribute :discount, currency: 'USD'
43
105
  end
44
106
  ```
45
107
 
46
- Now you can use the price attribute as a Money object:
108
+ Assignments are normalized to `Mint::Money`:
109
+
110
+ ```ruby
111
+ product = Product.new(price: 12, discount: '3.50')
112
+
113
+ product.price
114
+ # => #<Mint::Money ... USD 12.00>
115
+
116
+ product.discount
117
+ # => #<Mint::Money ... USD 3.50>
118
+ ```
119
+
120
+ Assigning a `Mint::Money` with a different currency raises `ArgumentError`:
121
+
122
+ ```ruby
123
+ Product.new(price: 12.to_money(:EUR))
124
+ # raises ArgumentError because the attribute only accepts USD
125
+ ```
126
+
127
+ ### Amount and currency columns
128
+
129
+ Use this when each row can store a different currency per record.
130
+
131
+ Migration:
132
+
133
+ ```ruby
134
+ class CreateOffers < ActiveRecord::Migration[7.1]
135
+ def change
136
+ create_table :offers do |t|
137
+ t.decimal :price_amount
138
+ t.string :price_currency
139
+
140
+ t.timestamps
141
+ end
142
+ end
143
+ end
144
+ ```
145
+
146
+ Model:
147
+
148
+ ```ruby
149
+ class Offer < ApplicationRecord
150
+ money_attribute :price
151
+ end
152
+ ```
153
+
154
+ The attribute is composed from `price_amount` and `price_currency`:
47
155
 
48
156
  ```ruby
49
- product = Product.ne(price: 100)
50
- puts product.price # => "$100.00"
157
+ offer = Offer.new(price: 15.to_money(:EUR))
158
+
159
+ offer.price
160
+ # => #<Mint::Money ... EUR 15.00>
161
+
162
+ offer.price_amount
163
+ # => 15.0
164
+
165
+ offer.price_currency
166
+ # => "EUR"
167
+ ```
168
+
169
+ When you assign a plain number or string, Minting::Rails uses `Mint.default_currency`:
170
+
171
+ ```ruby
172
+ offer = Offer.new(price: '12')
173
+
174
+ offer.price.currency_code
175
+ # => "USD"
176
+ ```
177
+
178
+ ### Custom column names
179
+
180
+ If your amount and currency columns do not follow the `<name>_amount` and `<name>_currency` convention, pass a mapping:
181
+
182
+ ```ruby
183
+ class Invoice < ApplicationRecord
184
+ money_attribute :total, mapping: {
185
+ total_amount: :amount,
186
+ currency_code: :currency
187
+ }
188
+ end
189
+ ```
190
+
191
+ The mapping keys are your database columns. The values must identify which column stores the `:amount` and which stores the `:currency`.
192
+
193
+ ## Querying
194
+
195
+ Fixed-currency attributes can be queried with `Mint::Money` values:
196
+
197
+ ```ruby
198
+ Product.where(price: 15.to_money(:USD))
199
+ ```
200
+
201
+ Composed attributes can also be queried with a money object:
202
+
203
+ ```ruby
204
+ Offer.where(price: 15.to_money(:EUR))
205
+ ```
206
+
207
+ You can still query the backing columns directly when that is clearer:
208
+
209
+ ```ruby
210
+ Offer.where(price_amount: 15, price_currency: 'EUR')
211
+ ```
212
+
213
+ ## Convenience methods
214
+
215
+ Minting::Rails adds a few small helpers:
216
+
217
+ ```ruby
218
+ 12.to_money(:USD)
219
+ 12.mint(:BRL)
220
+ 12.dollars
221
+ 12.euros
222
+ '12.50'.to_money(:USD)
223
+ '12.50'.mint(:BRL)
224
+ ```
225
+
226
+ These return `Mint::Money` instances.
227
+
228
+ ## Development
229
+
230
+ Clone the repository and install dependencies:
231
+
232
+ ```sh
233
+ bundle install
51
234
  ```
52
235
 
53
- ## To do
236
+ Run the test suite:
54
237
 
55
- - API Documentation
56
- - Internationalization
57
- - Publish 1.0 Beta
238
+ ```sh
239
+ bundle exec rake test
240
+ ```
241
+
242
+ The repository includes a dummy Rails application under `test/dummy` for exercising the engine in a Rails environment.
243
+
244
+ ## Releasing
245
+
246
+ Update the version in `lib/minting/money_attribute/version.rb`, update release notes, and build the gem:
247
+
248
+ ```sh
249
+ gem build minting-rails.gemspec
250
+ ```
251
+
252
+ Publishing is configured for RubyGems.org.
58
253
 
59
254
  ## Contributing
60
255
 
61
- Contribution directions go here.
256
+ Bug reports and pull requests are welcome on GitHub at [gferraz/minting-rails](https://github.com/gferraz/minting-rails).
257
+
258
+ Before opening a pull request, please run:
259
+
260
+ ```sh
261
+ bundle exec rake test
262
+ ```
62
263
 
63
264
  ## License
64
265
 
65
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
266
+ The gem is available as open source under the terms of the [MIT License](MIT-LICENSE).
@@ -1,26 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mint
4
- include ActiveSupport::Configurable
4
+ module MoneyAttribute
5
+ class Configuration
6
+ attr_accessor :added_currencies, :enabled_currencies, :default_currency,
7
+ :rounding_mode, :default_format
5
8
 
6
- def self.assert_valid_currency!(currency)
7
- if currency.is_a? Mint::Currency
8
- code = currency.code
9
- else
10
- code = currency.to_s
11
- currency = Mint.currency(code)
9
+ def initialize
10
+ @added_currencies = []
11
+ @enabled_currencies = :all
12
+ @default_currency = 'USD'
13
+ @rounding_mode = nil
14
+ @default_format = nil
15
+ end
12
16
  end
13
- return currency if valid_currency_codes.include?(code)
17
+ end
18
+
19
+ def self.config
20
+ @config ||= MoneyAttribute::Configuration.new
21
+ end
22
+
23
+ def self.configure
24
+ yield config if block_given?
25
+ @default_currency = nil
26
+ config
27
+ end
28
+
29
+ def self.assert_valid_currency!(currency)
30
+ currency = Mint.currency(currency)
31
+ return currency if config.valid_currency?(currency)
14
32
 
15
- raise ArgumentError,
16
- "Invalid currency '#{code}'. Please select a registered currency: #{valid_currency_codes}"
33
+ raise ArgumentError, "Invalid currency '#{currency.code}'. Please select a registered currency"
17
34
  end
18
35
 
19
36
  def self.default_currency
20
37
  @default_currency ||= Mint.assert_valid_currency!(config.default_currency)
21
38
  end
22
39
 
23
- def self.valid_currency_codes
24
- config.enabled_currencies == :all ? Mint.currencies.keys : config.enabled_currencies
40
+ def self.valid_currency?(currency)
41
+ currencies = config.enabled_currencies == :all ? Mint.currencies : config.enabled_currencies
42
+ currencies.include?(currency)
25
43
  end
26
44
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Mint
4
4
  module MoneyAttribute
5
- VERSION = '0.3.3'
5
+ VERSION = '0.4.2'
6
6
  end
7
7
  end
@@ -7,8 +7,15 @@ module Mint
7
7
  end
8
8
 
9
9
  config.to_prepare do
10
- Mint.config.added_currencies do |currency_data|
11
- Mint.register_currency(*currency_data)
10
+ Array(Mint.config.added_currencies).each do |currency_data|
11
+ if currency_data.respond_to?(:values_at)
12
+ code = currency_data[:currency] || currency_data['currency']
13
+ subunit = currency_data[:subunit] || currency_data['subunit']
14
+ symbol = currency_data[:symbol] || currency_data['symbol']
15
+ else
16
+ code, subunit, symbol = *currency_data
17
+ end
18
+ Mint.register_currency(code, subunit:, symbol:)
12
19
  end
13
20
  end
14
21
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minting-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gilson Ferraz
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-06-27 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: minting
@@ -16,14 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '0.3'
18
+ version: 1.0.0
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: '0.3'
25
+ version: 1.0.0
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: rails
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -68,7 +67,6 @@ metadata:
68
67
  changelog_uri: https://github.com/gferraz/minting-rails/releases
69
68
  bug_tracker_uri: https://github.com/gferraz/minting-rails/issues
70
69
  rubygems_mfa_required: 'true'
71
- post_install_message:
72
70
  rdoc_options: []
73
71
  require_paths:
74
72
  - lib
@@ -83,8 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
81
  - !ruby/object:Gem::Version
84
82
  version: '0'
85
83
  requirements: []
86
- rubygems_version: 3.5.14
87
- signing_key:
84
+ rubygems_version: 4.0.9
88
85
  specification_version: 4
89
86
  summary: Money attributes to ActiveRecord
90
87
  test_files: []