money-rails 1.3.0 → 1.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -0
- data/README.md +22 -13
- data/lib/money-rails/active_record/migration_extensions/schema_statements.rb +2 -8
- data/lib/money-rails/active_record/migration_extensions/table.rb +2 -8
- data/lib/money-rails/active_record/monetizable.rb +47 -45
- data/lib/money-rails/hooks.rb +6 -4
- data/lib/money-rails/version.rb +1 -1
- data/money-rails.gemspec +1 -0
- data/spec/active_record/monetizable_spec.rb +42 -6
- data/spec/dummy/app/models/product.rb +15 -10
- data/spec/dummy/config/application.rb +3 -0
- data/spec/dummy/db/migrate/20150213234410_add_special_price_to_products.rb +5 -0
- data/spec/dummy/db/migrate/20150217222612_add_lambda_price_to_products.rb +5 -0
- data/spec/dummy/db/migrate/20150303222230_add_skip_validation_price_cents_to_products.rb +5 -0
- data/spec/dummy/db/schema.rb +8 -5
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f8394a529d516a0e9f099291bdf744f6381b1b3
|
4
|
+
data.tar.gz: cde8c42671d4fee5881b3dce193d810e6aa8bc0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2cddc738c762f65dd0461852a040220d4bb4bd4016f2551871ed4b0069c6788dd4a899287670c169bb2e8809b6de6888e63fc0e0d9da8453309e53f9698c7fa8
|
7
|
+
data.tar.gz: ae99bf3bd2db13636253c3613e099f6de115b5a3f8768cbe5ea505ea77392cbf927e957ed56a836a8bce247970d8d88d8cbb8e92f71035e64a9c9664dd08eb4b
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,51 @@
|
|
2
2
|
|
3
3
|
## master (next release)
|
4
4
|
|
5
|
+
## 1.3.0
|
6
|
+
|
7
|
+
- Use currency_column[:postfix] to automatically determine currency column.
|
8
|
+
- Replacing getter method with attr_reader.
|
9
|
+
- Support the `disambiguate` option on humanized_money helper.
|
10
|
+
- Restore mongoid functionality on Rails < 4.0.
|
11
|
+
- Support multiple attributes w/ one call to `monetize` for AR.
|
12
|
+
- Add `add_monetize` and `remove_monetize` migration helpers, to fix a naming
|
13
|
+
clash introduced by the Rails 4.2 Postgres adapter Use correct amount for
|
14
|
+
validator when subunit is set directly.
|
15
|
+
- Fix store_accessor compatibility.
|
16
|
+
- Use `public_send` instead of `send` throughout the `monetize` method.
|
17
|
+
|
18
|
+
## 1.2.0
|
19
|
+
|
20
|
+
- Fixing tests which were broken on Rails 4.2.
|
21
|
+
- Add Rails 4.2 spec and update money dependency to 6.5.0.
|
22
|
+
|
23
|
+
## 1.1.0
|
24
|
+
|
25
|
+
- Update dependencies to money 6.4.x and monetize 1.0.x.
|
26
|
+
- Make subunit setter (e.g. `#price_cents=`) set the `before_type_cast...` va
|
27
|
+
riable. (Fixes validation errors.)
|
28
|
+
- use HashWithIndifferentAccess instead of Hash for
|
29
|
+
ActiveRecord::Base::monetized_attributes
|
30
|
+
- Let the 'monetize' test helper work when testing against the model's class,
|
31
|
+
as well as an instance of that class.
|
32
|
+
- Remove additional underscore in postfix comment
|
33
|
+
- Rescue UnknownCurrency within ActiveRecord
|
34
|
+
- Upgrade specs to RSpec 3
|
35
|
+
- Use #respond_to? instead of #try? when monetizing an aliased attribute.
|
36
|
+
- Allow aliased attributes to be monetized
|
37
|
+
- Fix compatability issue with Rails 4.2
|
38
|
+
- Allow empty string as thousands separator.
|
39
|
+
- Allow using a lambda to set default_currency
|
40
|
+
|
41
|
+
## 1.0.0
|
42
|
+
|
43
|
+
- Refactoring MoneyRails::ActiveModel::MoneyValidator#validate_each
|
44
|
+
- Update dependencies to money 6.2.x and monetize 0.4.x.
|
45
|
+
- Rescue from unknown currency errors on mongoization
|
46
|
+
- Add specs for Mongoize with invalid currency
|
47
|
+
- Add dedicated gemfiles and specs for Mongoid 3 and 4
|
48
|
+
- Show actual value of Money object in validation error message
|
49
|
+
|
5
50
|
## 0.12.0
|
6
51
|
- Add allow_nil chain for monetize test helper
|
7
52
|
- Add testing tasks for rails 4.1
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# RubyMoney - Money-Rails [](http://coderwall.com/alup)
|
2
2
|
|
3
|
-
[](http://badge.fury.io/rb/money-rails)
|
4
|
+
[](http://travis-ci.org/RubyMoney/money-rails)
|
5
|
+
[](https://gemnasium.com/RubyMoney/money-rails)
|
6
|
+
[](https://codeclimate.com/github/RubyMoney/money-rails)
|
7
|
+
[](http://opensource.org/licenses/MIT)
|
8
8
|
|
9
9
|
## Introduction
|
10
10
|
|
@@ -115,15 +115,17 @@ can use the ```remove_money``` helper.
|
|
115
115
|
|
116
116
|
##### Notice for Rails >= 4.2 and PG adapter
|
117
117
|
|
118
|
-
Due the
|
119
|
-
|
118
|
+
Due to the addition of the `money` column type for PostgreSQL in Rails 4.2, you
|
119
|
+
will need to use `add_monetize` instead of `add_money` column. If you're adding
|
120
|
+
the column within a `create_table` block, use `t.monetize`, and use
|
121
|
+
`remove_monetize` to remove the column.
|
120
122
|
|
121
123
|
#### Allow nil values
|
122
124
|
|
123
125
|
If you want to allow nil and/or blank values to a specific
|
124
126
|
monetized field, you can use the `:allow_nil` parameter:
|
125
127
|
|
126
|
-
```
|
128
|
+
```ruby
|
127
129
|
# in Product model
|
128
130
|
monetize :optional_price_cents, :allow_nil => true
|
129
131
|
|
@@ -160,6 +162,13 @@ are aggregate methods and you wish to avoid executing them on every record save.
|
|
160
162
|
monetize :price_in_a_range_cents, :disable_validation => true
|
161
163
|
```
|
162
164
|
|
165
|
+
You can also skip validations independently from each other by simply passing `false`
|
166
|
+
to the validation you are willing to skip, like this:
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
monetize :price_in_a_range_cents, :numericality => false
|
170
|
+
```
|
171
|
+
|
163
172
|
### Mongoid 2.x and 3.x
|
164
173
|
|
165
174
|
`Money` is available as a field type to supply during a field definition:
|
@@ -323,7 +332,7 @@ t.amount == Money.new(2500, "CAD") # true
|
|
323
332
|
|
324
333
|
You can handle a bunch of configuration params through ```money.rb``` initializer:
|
325
334
|
|
326
|
-
```
|
335
|
+
```ruby
|
327
336
|
MoneyRails.configure do |config|
|
328
337
|
|
329
338
|
# To set the default currency
|
@@ -453,23 +462,23 @@ use the helper.
|
|
453
462
|
|
454
463
|
* the `monetize` matcher
|
455
464
|
|
456
|
-
```
|
465
|
+
```ruby
|
457
466
|
monetize(:price_cents).should be_true
|
458
467
|
```
|
459
468
|
This will ensure that a column called `price_cents` is being monetized.
|
460
469
|
|
461
|
-
```
|
470
|
+
```ruby
|
462
471
|
monetize(:price_cents).allow_nil.should be_true
|
463
472
|
```
|
464
473
|
By using `allow_nil` you can specify money attributes that accept nil values.
|
465
474
|
|
466
|
-
```
|
475
|
+
```ruby
|
467
476
|
monetize(:price_cents).as(:discount_value).should be_true
|
468
477
|
```
|
469
478
|
By using `as` chain you can specify the exact name to which a monetized
|
470
479
|
column is being mapped.
|
471
480
|
|
472
|
-
```
|
481
|
+
```ruby
|
473
482
|
monetize(:price_cents).with_currency(:gbp).should be_true
|
474
483
|
```
|
475
484
|
|
@@ -3,17 +3,11 @@ module MoneyRails
|
|
3
3
|
module MigrationExtensions
|
4
4
|
module SchemaStatements
|
5
5
|
def add_money(table_name, accessor, options={})
|
6
|
-
|
7
|
-
column_present, *opts = OptionsExtractor.extract attribute, table_name, accessor, options
|
8
|
-
add_column *opts if column_present
|
9
|
-
end
|
6
|
+
add_monetize(table_name, accessor, options)
|
10
7
|
end
|
11
8
|
|
12
9
|
def remove_money(table_name, accessor, options={})
|
13
|
-
|
14
|
-
column_present, table_name, column_name, _, _ = OptionsExtractor.extract attribute, table_name, accessor, options
|
15
|
-
remove_column table_name, column_name if column_present
|
16
|
-
end
|
10
|
+
remove_monetize(table_name, accessor, options)
|
17
11
|
end
|
18
12
|
end
|
19
13
|
end
|
@@ -3,17 +3,11 @@ module MoneyRails
|
|
3
3
|
module MigrationExtensions
|
4
4
|
module Table
|
5
5
|
def money(accessor, options={})
|
6
|
-
|
7
|
-
column_present, _, *opts = OptionsExtractor.extract attribute, :no_table, accessor, options
|
8
|
-
column *opts if column_present
|
9
|
-
end
|
6
|
+
monetize(accessor, options)
|
10
7
|
end
|
11
8
|
|
12
9
|
def remove_money(accessor, options={})
|
13
|
-
|
14
|
-
column_present, _, column_name, _, _ = OptionsExtractor.extract attribute, :no_table, accessor, options
|
15
|
-
remove column_name if column_present
|
16
|
-
end
|
10
|
+
remove_monetize(accessor, options)
|
17
11
|
end
|
18
12
|
end
|
19
13
|
end
|
@@ -5,9 +5,20 @@ require 'active_support/deprecation/reporting'
|
|
5
5
|
module MoneyRails
|
6
6
|
module ActiveRecord
|
7
7
|
module Monetizable
|
8
|
+
class ReadOnlyCurrencyException < StandardError; end
|
8
9
|
extend ActiveSupport::Concern
|
9
10
|
|
10
11
|
module ClassMethods
|
12
|
+
def monetized_attributes
|
13
|
+
monetized_attributes = @monetized_attributes || {}
|
14
|
+
|
15
|
+
if superclass.respond_to?(:monetized_attributes)
|
16
|
+
monetized_attributes.merge(superclass.monetized_attributes)
|
17
|
+
else
|
18
|
+
monetized_attributes
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
11
22
|
def monetize(*fields)
|
12
23
|
options = fields.extract_options!
|
13
24
|
|
@@ -15,11 +26,10 @@ module MoneyRails
|
|
15
26
|
# Stringify model field name
|
16
27
|
subunit_name = field.to_s
|
17
28
|
|
18
|
-
if options[:field_currency] || options[:target_name] ||
|
19
|
-
options[:model_currency]
|
29
|
+
if options[:field_currency] || options[:target_name] || options[:model_currency]
|
20
30
|
ActiveSupport::Deprecation.warn("You are using the old " \
|
21
|
-
|
22
|
-
|
31
|
+
"argument keys of the monetize command! Instead use :as, " \
|
32
|
+
":with_currency or :with_model_currency")
|
23
33
|
end
|
24
34
|
|
25
35
|
# Optional accessor to be run on an instance to detect currency
|
@@ -51,16 +61,7 @@ module MoneyRails
|
|
51
61
|
end
|
52
62
|
|
53
63
|
# Create a reverse mapping of the monetized attributes
|
54
|
-
|
55
|
-
if @monetized_attributes[name].present?
|
56
|
-
raise ArgumentError, "#{self} already has a monetized attribute called '#{name}'"
|
57
|
-
end
|
58
|
-
@monetized_attributes[name] = subunit_name
|
59
|
-
class << self
|
60
|
-
def monetized_attributes
|
61
|
-
@monetized_attributes || superclass.monetized_attributes
|
62
|
-
end
|
63
|
-
end unless respond_to? :monetized_attributes
|
64
|
+
track_monetized_attribute name, subunit_name
|
64
65
|
|
65
66
|
# Include numericality validations if needed.
|
66
67
|
# There are two validation options:
|
@@ -86,31 +87,21 @@ module MoneyRails
|
|
86
87
|
# monetize :price_in_a_range_cents, :disable_validation => true
|
87
88
|
if validation_enabled = MoneyRails.include_validations && !options[:disable_validation]
|
88
89
|
|
89
|
-
subunit_validation_options =
|
90
|
-
unless options.has_key? :subunit_numericality
|
91
|
-
true
|
92
|
-
else
|
93
|
-
options[:subunit_numericality]
|
94
|
-
end
|
95
|
-
|
96
|
-
money_validation_options =
|
97
|
-
unless options.has_key? :numericality
|
98
|
-
true
|
99
|
-
else
|
100
|
-
options[:numericality]
|
101
|
-
end
|
102
|
-
|
103
90
|
# This is a validation for the subunit
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
91
|
+
if subunit_numericality = options.fetch(:subunit_numericality, true)
|
92
|
+
validates subunit_name, {
|
93
|
+
:allow_nil => options[:allow_nil],
|
94
|
+
:numericality => subunit_numericality
|
95
|
+
}
|
96
|
+
end
|
108
97
|
|
109
98
|
# Allow only Money objects or Numeric values!
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
99
|
+
if numericality = options.fetch(:numericality, true)
|
100
|
+
validates name.to_sym, {
|
101
|
+
:allow_nil => options[:allow_nil],
|
102
|
+
'money_rails/active_model/money' => numericality
|
103
|
+
}
|
104
|
+
end
|
114
105
|
end
|
115
106
|
|
116
107
|
|
@@ -168,7 +159,7 @@ module MoneyRails
|
|
168
159
|
# the regular writer, which works with store_accessors
|
169
160
|
public_send("#{subunit_name}=", money.try(:cents))
|
170
161
|
elsif self.class.respond_to?(:attribute_aliases) &&
|
171
|
-
|
162
|
+
self.class.attribute_aliases.key?(subunit_name)
|
172
163
|
# If the attribute is aliased, make sure we write to the original
|
173
164
|
# attribute name or an error will be raised.
|
174
165
|
# (Note: 'attribute_aliases' doesn't exist in Rails 3.x, so we
|
@@ -182,14 +173,12 @@ module MoneyRails
|
|
182
173
|
money_currency = money.try(:currency)
|
183
174
|
|
184
175
|
# Update currency iso value if there is an instance currency attribute
|
185
|
-
if instance_currency_name.present? &&
|
186
|
-
respond_to?("#{instance_currency_name}=")
|
187
|
-
|
176
|
+
if instance_currency_name.present? && respond_to?("#{instance_currency_name}=")
|
188
177
|
public_send("#{instance_currency_name}=", money_currency.try(:iso_code))
|
189
178
|
else
|
190
179
|
current_currency = public_send("currency_for_#{name}")
|
191
180
|
if money_currency && current_currency != money_currency.id
|
192
|
-
raise "Can't change readonly currency '#{current_currency}' to '#{money_currency}' for field '#{name}'"
|
181
|
+
raise ReadOnlyCurrencyException.new("Can't change readonly currency '#{current_currency}' to '#{money_currency}' for field '#{name}'")
|
193
182
|
end
|
194
183
|
end
|
195
184
|
|
@@ -209,15 +198,16 @@ module MoneyRails
|
|
209
198
|
define_method "currency_for_#{name}" do
|
210
199
|
instance_currency_name_with_postfix = "#{name}#{MoneyRails::Configuration.currency_column[:postfix]}"
|
211
200
|
|
212
|
-
if instance_currency_name.present? &&
|
213
|
-
|
214
|
-
Money::Currency.find(public_send(instance_currency_name))
|
201
|
+
if instance_currency_name.present? && respond_to?(instance_currency_name) &&
|
202
|
+
Money::Currency.find(public_send(instance_currency_name))
|
215
203
|
|
216
204
|
Money::Currency.find(public_send(instance_currency_name))
|
205
|
+
elsif field_currency_name.respond_to?(:call)
|
206
|
+
Money::Currency.find(field_currency_name.call(self))
|
217
207
|
elsif field_currency_name
|
218
208
|
Money::Currency.find(field_currency_name)
|
219
209
|
elsif respond_to?(instance_currency_name_with_postfix) &&
|
220
|
-
|
210
|
+
Money::Currency.find(public_send(instance_currency_name_with_postfix))
|
221
211
|
|
222
212
|
Money::Currency.find(public_send(instance_currency_name_with_postfix))
|
223
213
|
elsif self.class.respond_to?(:currency)
|
@@ -250,6 +240,18 @@ module MoneyRails
|
|
250
240
|
end
|
251
241
|
end
|
252
242
|
end
|
243
|
+
|
244
|
+
private
|
245
|
+
|
246
|
+
def track_monetized_attribute(name, value)
|
247
|
+
@monetized_attributes ||= {}.with_indifferent_access
|
248
|
+
|
249
|
+
if @monetized_attributes[name].present?
|
250
|
+
raise ArgumentError, "#{self} already has a monetized attribute called '#{name}'"
|
251
|
+
end
|
252
|
+
|
253
|
+
@monetized_attributes[name] = value
|
254
|
+
end
|
253
255
|
end
|
254
256
|
end
|
255
257
|
end
|
data/lib/money-rails/hooks.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module MoneyRails
|
2
2
|
class Hooks
|
3
|
+
PG_ADAPTERS = %w(activerecord-jdbcpostgresql-adapter postgresql postgis)
|
4
|
+
|
3
5
|
def self.init
|
4
6
|
# For Active Record
|
5
7
|
ActiveSupport.on_load(:active_record) do
|
@@ -15,14 +17,14 @@ module MoneyRails
|
|
15
17
|
else
|
16
18
|
false
|
17
19
|
end
|
18
|
-
|
20
|
+
current_adapter = ::ActiveRecord::Base.connection_config[:adapter]
|
21
|
+
postgresql_with_money = rails42 && PG_ADAPTERS.include?(current_adapter)
|
19
22
|
end
|
20
23
|
|
21
24
|
require "money-rails/active_record/migration_extensions/options_extractor"
|
22
25
|
%w{schema_statements table}.each do |file|
|
23
|
-
|
24
|
-
|
25
|
-
else
|
26
|
+
require "money-rails/active_record/migration_extensions/#{file}_pg_rails4"
|
27
|
+
if !postgresql_with_money
|
26
28
|
require "money-rails/active_record/migration_extensions/#{file}"
|
27
29
|
end
|
28
30
|
end
|
data/lib/money-rails/version.rb
CHANGED
data/money-rails.gemspec
CHANGED
@@ -34,4 +34,5 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.add_development_dependency "rails", ">= 3.0"
|
35
35
|
s.add_development_dependency "rspec-rails", "~> 3.0"
|
36
36
|
s.add_development_dependency 'database_cleaner', ['>= 0.8.0', '< 1.4.0']
|
37
|
+
s.add_development_dependency 'test-unit', '~> 3.0' if RUBY_VERSION =~ /^2\.2/
|
37
38
|
end
|
@@ -2,6 +2,10 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
class Sub < Product; end
|
4
4
|
|
5
|
+
class SubProduct < Product
|
6
|
+
monetize :special_price_cents
|
7
|
+
end
|
8
|
+
|
5
9
|
if defined? ActiveRecord
|
6
10
|
describe MoneyRails::ActiveRecord::Monetizable do
|
7
11
|
describe "monetize" do
|
@@ -10,7 +14,8 @@ if defined? ActiveRecord
|
|
10
14
|
:bonus_cents => 200, :optional_price => 100,
|
11
15
|
:sale_price_amount => 1200, :delivery_fee_cents => 100,
|
12
16
|
:restock_fee_cents => 2000,
|
13
|
-
:reduced_price_cents => 1500, :reduced_price_currency => :lvl
|
17
|
+
:reduced_price_cents => 1500, :reduced_price_currency => :lvl,
|
18
|
+
:lambda_price_cents => 4000)
|
14
19
|
end
|
15
20
|
|
16
21
|
let(:service) do
|
@@ -21,6 +26,10 @@ if defined? ActiveRecord
|
|
21
26
|
expect(Sub.monetized_attributes).to eq(Product.monetized_attributes)
|
22
27
|
end
|
23
28
|
|
29
|
+
it "should be inherited by subclasses with new monetized attribute" do
|
30
|
+
expect(SubProduct.monetized_attributes).to eq(Product.monetized_attributes.merge(special_price: "special_price_cents"))
|
31
|
+
end
|
32
|
+
|
24
33
|
it "attaches a Money object to model field" do
|
25
34
|
expect(product.price).to be_an_instance_of(Money)
|
26
35
|
expect(product.discount_value).to be_an_instance_of(Money)
|
@@ -44,7 +53,7 @@ if defined? ActiveRecord
|
|
44
53
|
|
45
54
|
it "assigns the correct value from a Money object using create" do
|
46
55
|
product = Product.create(:price => Money.new(3210, "USD"), :discount => 150,
|
47
|
-
|
56
|
+
:bonus_cents => 200, :optional_price => 100)
|
48
57
|
expect(product.valid?).to be_truthy
|
49
58
|
expect(product.price_cents).to eq(3210)
|
50
59
|
end
|
@@ -58,7 +67,7 @@ if defined? ActiveRecord
|
|
58
67
|
product = Product.new
|
59
68
|
expect {
|
60
69
|
product.price = Money.new(10, "RUB")
|
61
|
-
}.to raise_error("Can't change readonly currency 'USD' to 'RUB' for field 'price'")
|
70
|
+
}.to raise_error(MoneyRails::ActiveRecord::Monetizable::ReadOnlyCurrencyException, "Can't change readonly currency 'USD' to 'RUB' for field 'price'")
|
62
71
|
end
|
63
72
|
|
64
73
|
it "raises an error if trying to create two attributes with the same name" do
|
@@ -69,6 +78,17 @@ if defined? ActiveRecord
|
|
69
78
|
end.to raise_error
|
70
79
|
end
|
71
80
|
|
81
|
+
it "allows subclass to redefine attribute with the same name" do
|
82
|
+
class SubProduct < Product
|
83
|
+
monetize :discount, as: :discount_price, with_currency: :gbp
|
84
|
+
end
|
85
|
+
|
86
|
+
sub_product = SubProduct.new(discount: 100)
|
87
|
+
|
88
|
+
expect(sub_product.discount_price).to be_an_instance_of(Money)
|
89
|
+
expect(sub_product.discount_price.currency.id).to equal :gbp
|
90
|
+
end
|
91
|
+
|
72
92
|
it "respects :as argument" do
|
73
93
|
expect(product.discount_value).to eq(Money.new(150, "USD"))
|
74
94
|
end
|
@@ -125,6 +145,16 @@ if defined? ActiveRecord
|
|
125
145
|
expect(product.valid?).to be_truthy
|
126
146
|
end
|
127
147
|
|
148
|
+
it "separately skips price validations" do
|
149
|
+
product.skip_validation_price = 'hundred thousands'
|
150
|
+
expect(product.save).to be_truthy
|
151
|
+
end
|
152
|
+
|
153
|
+
it "separately skips subunit validations" do
|
154
|
+
product.skip_validation_price_cents = 'ten million'
|
155
|
+
expect(product.save).to be_truthy
|
156
|
+
end
|
157
|
+
|
128
158
|
it "fails validation with the proper error message if money value is invalid decimal" do
|
129
159
|
product.price = "12.23.24"
|
130
160
|
expect(product.save).to be_falsey
|
@@ -162,7 +192,7 @@ if defined? ActiveRecord
|
|
162
192
|
expect(service.save).to be_truthy
|
163
193
|
end
|
164
194
|
|
165
|
-
|
195
|
+
it "passes validation if money value is a Float" do
|
166
196
|
product.price = 12.34
|
167
197
|
expect(product.save).to be_truthy
|
168
198
|
end
|
@@ -430,6 +460,11 @@ if defined? ActiveRecord
|
|
430
460
|
expect(service.save).to be_truthy
|
431
461
|
expect(service.charge.cents).to eq(200)
|
432
462
|
expect(service.charge.currency_as_string).to eq("USD")
|
463
|
+
|
464
|
+
product.lambda_price = "32"
|
465
|
+
expect(product.save).to be_truthy
|
466
|
+
expect(product.lambda_price.cents).to eq(3200)
|
467
|
+
expect(product.lambda_price.currency_as_string).to eq("CAD")
|
433
468
|
end
|
434
469
|
|
435
470
|
it "overrides default currency with model currency, in fixnum assignments" do
|
@@ -468,7 +503,7 @@ if defined? ActiveRecord
|
|
468
503
|
|
469
504
|
it "sets field to nil, in instantiation if allow_nil is set" do
|
470
505
|
pr = Product.new(:optional_price => nil, :price_cents => 5320,
|
471
|
-
|
506
|
+
:discount => 350, :bonus_cents => 320)
|
472
507
|
expect(pr.optional_price).to be_nil
|
473
508
|
expect(pr.save).to be_truthy
|
474
509
|
expect(pr.optional_price).to be_nil
|
@@ -506,7 +541,8 @@ if defined? ActiveRecord
|
|
506
541
|
:bonus => Money.new(10,'GBP'),
|
507
542
|
:discount => 10,
|
508
543
|
:sale_price_amount => 1234,
|
509
|
-
:sale_price_currency_code => 'USD'
|
544
|
+
:sale_price_currency_code => 'USD'
|
545
|
+
)
|
510
546
|
|
511
547
|
expect(product.sale_price.currency_as_string).to eq('USD')
|
512
548
|
|
@@ -19,18 +19,23 @@ class Product < ActiveRecord::Base
|
|
19
19
|
|
20
20
|
# Use currency column to determine currency for this field only
|
21
21
|
monetize :sale_price_amount, :as => :sale_price,
|
22
|
-
|
22
|
+
:with_model_currency => :sale_price_currency_code
|
23
23
|
|
24
24
|
monetize :price_in_a_range_cents, :allow_nil => true,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
:
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
:subunit_numericality => {
|
26
|
+
:greater_than => 0,
|
27
|
+
:less_than_or_equal_to => 10000 },
|
28
|
+
:numericality => {
|
29
|
+
:greater_than => 0,
|
30
|
+
:less_than_or_equal_to => 100,
|
31
|
+
:message => "Must be greater than zero and less than $100"
|
32
|
+
}
|
33
|
+
|
34
|
+
# Skip validations separately from each other
|
35
|
+
monetize :skip_validation_price_cents, subunit_numericality: false, numericality: false, allow_nil: true
|
36
|
+
|
37
|
+
# Override default currency (EUR) with a specific one (CAD) for this field only, from a lambda
|
38
|
+
monetize :lambda_price_cents, with_currency: ->(product) { Rails.configuration.lambda_test }, allow_nil: true
|
34
39
|
|
35
40
|
attr_accessor :accessor_price_cents
|
36
41
|
monetize :accessor_price_cents, disable_validation: true
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -11,16 +11,16 @@
|
|
11
11
|
#
|
12
12
|
# It's strongly recommended that you check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(version:
|
14
|
+
ActiveRecord::Schema.define(version: 20150303222230) do
|
15
15
|
|
16
|
-
create_table "dummy_products", force:
|
16
|
+
create_table "dummy_products", force: :cascade do |t|
|
17
17
|
t.string "currency"
|
18
18
|
t.integer "price_cents"
|
19
19
|
t.datetime "created_at"
|
20
20
|
t.datetime "updated_at"
|
21
21
|
end
|
22
22
|
|
23
|
-
create_table "products", force:
|
23
|
+
create_table "products", force: :cascade do |t|
|
24
24
|
t.integer "price_cents"
|
25
25
|
t.integer "discount"
|
26
26
|
t.datetime "created_at"
|
@@ -36,16 +36,19 @@ ActiveRecord::Schema.define(version: 20150126231442) do
|
|
36
36
|
t.integer "restock_fee_cents"
|
37
37
|
t.integer "reduced_price_cents"
|
38
38
|
t.string "reduced_price_currency"
|
39
|
+
t.integer "special_price_cents"
|
40
|
+
t.integer "lambda_price_cents"
|
41
|
+
t.string "skip_validation_price_cents"
|
39
42
|
end
|
40
43
|
|
41
|
-
create_table "services", force:
|
44
|
+
create_table "services", force: :cascade do |t|
|
42
45
|
t.integer "charge_cents"
|
43
46
|
t.integer "discount_cents"
|
44
47
|
t.datetime "created_at"
|
45
48
|
t.datetime "updated_at"
|
46
49
|
end
|
47
50
|
|
48
|
-
create_table "transactions", force:
|
51
|
+
create_table "transactions", force: :cascade do |t|
|
49
52
|
t.integer "amount_cents"
|
50
53
|
t.integer "tax_cents"
|
51
54
|
t.string "currency"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: money-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Loupasakis
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-04-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: money
|
@@ -197,6 +197,9 @@ files:
|
|
197
197
|
- spec/dummy/db/migrate/20141005075025_add_aliased_attr_to_products.rb
|
198
198
|
- spec/dummy/db/migrate/20150107061030_add_delivery_fee_cents_and_restock_fee_cents_to_product.rb
|
199
199
|
- spec/dummy/db/migrate/20150126231442_add_reduced_price_to_products.rb
|
200
|
+
- spec/dummy/db/migrate/20150213234410_add_special_price_to_products.rb
|
201
|
+
- spec/dummy/db/migrate/20150217222612_add_lambda_price_to_products.rb
|
202
|
+
- spec/dummy/db/migrate/20150303222230_add_skip_validation_price_cents_to_products.rb
|
200
203
|
- spec/dummy/db/schema.rb
|
201
204
|
- spec/dummy/db/structure.sql
|
202
205
|
- spec/dummy/public/404.html
|
@@ -285,6 +288,9 @@ test_files:
|
|
285
288
|
- spec/dummy/db/migrate/20141005075025_add_aliased_attr_to_products.rb
|
286
289
|
- spec/dummy/db/migrate/20150107061030_add_delivery_fee_cents_and_restock_fee_cents_to_product.rb
|
287
290
|
- spec/dummy/db/migrate/20150126231442_add_reduced_price_to_products.rb
|
291
|
+
- spec/dummy/db/migrate/20150213234410_add_special_price_to_products.rb
|
292
|
+
- spec/dummy/db/migrate/20150217222612_add_lambda_price_to_products.rb
|
293
|
+
- spec/dummy/db/migrate/20150303222230_add_skip_validation_price_cents_to_products.rb
|
288
294
|
- spec/dummy/db/schema.rb
|
289
295
|
- spec/dummy/db/structure.sql
|
290
296
|
- spec/dummy/public/404.html
|