easy_rails_money 0.0.8 → 0.0.9.pre
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.
- data/README.md +6 -0
- data/lib/easy_rails_money/active_record.rb +21 -0
- data/lib/easy_rails_money/active_record/money_dsl.rb +15 -0
- data/lib/easy_rails_money/money_validator.rb +25 -0
- data/lib/easy_rails_money/version.rb +1 -1
- data/spec/active_record/validates_money_spec.rb +95 -0
- data/spec/loan_with_currency_and_validation_model_spec_helper.rb +12 -0
- metadata +11 -9
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
[](https://travis-ci.org/deepak/easy_rails_money)
|
2
2
|
[](https://gemnasium.com/deepak/easy_rails_money)
|
3
3
|
[](https://codeclimate.com/github/deepak/easy_rails_money)
|
4
|
+
[](http://badge.fury.io/rb/easy_rails_money)
|
4
5
|
|
5
6
|
# EasyRailsMoney
|
6
7
|
|
@@ -377,3 +378,8 @@ loan_usd.currency # equals Money::Currency.new(:usd)
|
|
377
378
|
do we want a Money::Currency object back?
|
378
379
|
not decided
|
379
380
|
see currency_persistence_spec.rb
|
381
|
+
14. make sure re-opening and redefining money dsl methods work
|
382
|
+
eg. moving from individual currencies to single currency
|
383
|
+
15. document. methods defined inside activerecord's scope
|
384
|
+
move to a helper, no that its namespace is not polluted
|
385
|
+
16. two specs tagged with fixme in validates_money_spec failing
|
@@ -2,6 +2,7 @@ require "easy_rails_money/active_record/money_dsl"
|
|
2
2
|
require "easy_rails_money/active_record/migration/schema_statements"
|
3
3
|
require "easy_rails_money/active_record/migration/table"
|
4
4
|
require "easy_rails_money/active_record/migration/table_definition"
|
5
|
+
require "easy_rails_money/money_validator"
|
5
6
|
|
6
7
|
ActiveRecord::Base.send :include, EasyRailsMoney::ActiveRecord::MoneyDsl
|
7
8
|
|
@@ -9,4 +10,24 @@ ActiveRecord::Migration.send :include, EasyRailsMoney::ActiveRecord::Migration::
|
|
9
10
|
|
10
11
|
ActiveRecord::ConnectionAdapters::TableDefinition.send :include, EasyRailsMoney::ActiveRecord::Migration::TableDefinition
|
11
12
|
ActiveRecord::ConnectionAdapters::Table.send :include, EasyRailsMoney::ActiveRecord::Migration::Table
|
13
|
+
|
14
|
+
class ActiveRecord::Base
|
15
|
+
def self.validates_money *args
|
16
|
+
options = args.extract_options!
|
17
|
+
validates_with EasyRailsMoney::MoneyValidator, options.merge(:attributes => args)
|
12
18
|
|
19
|
+
# validates lower-level columns
|
20
|
+
args.each do |column_name|
|
21
|
+
validates "#{column_name}_money", :numericality => { only_integer: true, greater_than_or_equal_to: 0 }, :allow_nil => options[:allow_nil]
|
22
|
+
end
|
23
|
+
|
24
|
+
allowed_currency = options[:allowed_currency] || Money::Currency.table.keys
|
25
|
+
if single_currency?
|
26
|
+
validates :currency, :inclusion => { in: allowed_currency }, :allow_nil => options[:allow_nil]
|
27
|
+
else
|
28
|
+
args.each do |column_name|
|
29
|
+
validates "#{column_name}_currency", :presence => true, :inclusion => { in: allowed_currency }, :allow_nil => options[:allow_nil]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -5,6 +5,12 @@ module EasyRailsMoney
|
|
5
5
|
module ActiveRecord
|
6
6
|
module MoneyDsl
|
7
7
|
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
def money_attributes
|
11
|
+
attributes.keys.select {|x| x =~ /^(.+)_money/ }.map {|x| x.split('_')[0..-2].join }
|
12
|
+
end
|
13
|
+
end
|
8
14
|
|
9
15
|
module ClassMethods
|
10
16
|
attr_accessor :single_currency
|
@@ -69,6 +75,15 @@ module EasyRailsMoney
|
|
69
75
|
# currency is stored in a seperate common column
|
70
76
|
return Money.new(value, self.currency)
|
71
77
|
end # define_method setter
|
78
|
+
|
79
|
+
define_method "currency=" do |value|
|
80
|
+
if value.nil?
|
81
|
+
money_attributes.map do |name|
|
82
|
+
send "#{name}=", nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
super value
|
86
|
+
end
|
72
87
|
else
|
73
88
|
# TODO: test if Memoization will make any difference
|
74
89
|
define_method column_name do |*args|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'active_support/core_ext/array/extract_options'
|
2
|
+
|
3
|
+
module EasyRailsMoney
|
4
|
+
# TODO: there are a lot of validations here. customizing the messages
|
5
|
+
# for all of them seems cumbersome. if needed write your own. or even patch
|
6
|
+
# also while calling the individual validators in validates_money
|
7
|
+
# only allow_nil is passed around (as it was needed). test for other
|
8
|
+
# like if and unless as well
|
9
|
+
class MoneyValidator < ActiveModel::EachValidator
|
10
|
+
def validate_each(record, attribute, value)
|
11
|
+
if options[:allow_nil]
|
12
|
+
return if value.nil?
|
13
|
+
else
|
14
|
+
if value.nil?
|
15
|
+
record.errors[attribute] << "cannot be nil"
|
16
|
+
return
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if value.fractional < 0
|
21
|
+
record.errors[attribute] << "cannot be negative"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_record_spec_helper'
|
3
|
+
|
4
|
+
describe "Validation" do
|
5
|
+
context "single currency" do
|
6
|
+
def loan_model
|
7
|
+
Object.send(:remove_const, "LoanWithCurrency") if defined? LoanWithCurrency
|
8
|
+
migrate CreateTableDefinition::CreateLoanWithCurrency
|
9
|
+
load 'loan_with_currency_model_spec_helper.rb'
|
10
|
+
LoanWithCurrency
|
11
|
+
end
|
12
|
+
|
13
|
+
# subject can be delayed bound ie. after some changes
|
14
|
+
def add_expectations subject, allow_nil
|
15
|
+
expect(subject.class.validators.length).to eq 5
|
16
|
+
expect(subject.class.validators.select {|x| x.is_a? EasyRailsMoney::MoneyValidator }.length).to eq 1
|
17
|
+
expect(subject.class.validators.map {|x| x.options[:allow_nil] }.uniq).to eq [allow_nil]
|
18
|
+
|
19
|
+
EasyRailsMoney::MoneyValidator.any_instance.should_receive(:validate_each).with(subject, :principal, subject.principal)
|
20
|
+
EasyRailsMoney::MoneyValidator.any_instance.should_receive(:validate_each).with(subject, :repaid, subject.repaid)
|
21
|
+
EasyRailsMoney::MoneyValidator.any_instance.should_receive(:validate_each).with(subject, :npa, subject.npa)
|
22
|
+
end
|
23
|
+
|
24
|
+
context "do not allow nil" do
|
25
|
+
let(:subject) do
|
26
|
+
model = loan_model
|
27
|
+
model.instance_eval {
|
28
|
+
validates_money :principal, :repaid, :npa, :allow_nil => false, :allowed_currency => %w[inr usd sgd]
|
29
|
+
}
|
30
|
+
|
31
|
+
loan = model.new
|
32
|
+
loan.name = "loan having some values"
|
33
|
+
loan.principal = 100 * 100
|
34
|
+
loan.repaid = 50 * 100
|
35
|
+
loan.npa = 10 * 100
|
36
|
+
loan
|
37
|
+
end
|
38
|
+
|
39
|
+
it "is valid when it is a Money object" do
|
40
|
+
add_expectations subject, false
|
41
|
+
expect(subject).to be_valid
|
42
|
+
end
|
43
|
+
|
44
|
+
it "is in-valid if values are nil and allow_nil is false" do
|
45
|
+
subject.principal = nil
|
46
|
+
add_expectations subject, false
|
47
|
+
expect(subject).not_to be_valid
|
48
|
+
expect(subject.errors.messages).to eq :principal_money=>["is not a number"]
|
49
|
+
end
|
50
|
+
|
51
|
+
it "is in-valid if currency is nil and allow_nil is false" do
|
52
|
+
old = subject.principal
|
53
|
+
expect { subject.currency = nil }.to change { subject.principal }.from(old).to(nil)
|
54
|
+
expect(subject.attributes["currency"]).to be_nil
|
55
|
+
add_expectations subject, false
|
56
|
+
expect(subject).not_to be_valid
|
57
|
+
puts subject.errors.messages
|
58
|
+
expect(subject.errors.messages).to eq(:principal_money=>["is not a number"], :repaid_money=>["is not a number"], :npa_money=>["is not a number"], :currency=>["is not included in the list"])
|
59
|
+
end
|
60
|
+
end # context "do not allow nil"
|
61
|
+
|
62
|
+
context "allow nil", :fixme do
|
63
|
+
let(:subject) do
|
64
|
+
model = loan_model
|
65
|
+
model.instance_eval {
|
66
|
+
validates_money :principal, :repaid, :npa, :allow_nil => true, :allowed_currency => %w[inr usd sgd]
|
67
|
+
}
|
68
|
+
|
69
|
+
loan = model.new
|
70
|
+
loan.name = "loan having nil values"
|
71
|
+
loan.principal = nil
|
72
|
+
loan.repaid = nil
|
73
|
+
loan.npa = nil
|
74
|
+
loan
|
75
|
+
end
|
76
|
+
|
77
|
+
it "is valid if currency is nil and allow_nil is true" do
|
78
|
+
subject.currency = nil
|
79
|
+
expect(subject.principal).to be_nil
|
80
|
+
expect(subject.attributes["currency"]).to be_nil
|
81
|
+
|
82
|
+
add_expectations subject, true
|
83
|
+
expect(subject).to be_valid
|
84
|
+
end
|
85
|
+
|
86
|
+
it "is in-valid if currency is not allowed" do
|
87
|
+
subject.currency = "foo"
|
88
|
+
add_expectations subject, true
|
89
|
+
expect(subject).not_to be_valid
|
90
|
+
end
|
91
|
+
end # context "allow nil"
|
92
|
+
|
93
|
+
pending "check lower-level validations"
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class LoanWithCurrencyAndValidation < ActiveRecord::Base
|
2
|
+
self.table_name = "loans"
|
3
|
+
attr_accessible :name
|
4
|
+
|
5
|
+
with_currency(:inr) do
|
6
|
+
money :principal
|
7
|
+
money :repaid
|
8
|
+
money :npa
|
9
|
+
end
|
10
|
+
|
11
|
+
validates_money :principal, :repaid, :npa, :allow_nil => true, :allowed_currency => %w[inr usd sgd]
|
12
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_rails_money
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.9.pre
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Deepak Kannan
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: money
|
@@ -195,13 +195,16 @@ files:
|
|
195
195
|
- lib/easy_rails_money/active_record/money_dsl.rb
|
196
196
|
- lib/easy_rails_money/configuration.rb
|
197
197
|
- lib/easy_rails_money/money_dsl_helper.rb
|
198
|
+
- lib/easy_rails_money/money_validator.rb
|
198
199
|
- lib/easy_rails_money/version.rb
|
199
200
|
- spec/active_record/currency_persistence_spec.rb
|
200
201
|
- spec/active_record/migration_spec.rb
|
201
202
|
- spec/active_record/money_dsl_spec.rb
|
203
|
+
- spec/active_record/validates_money_spec.rb
|
202
204
|
- spec/active_record_spec_helper.rb
|
203
205
|
- spec/configuration_spec.rb
|
204
206
|
- spec/loan_model_spec_helper.rb
|
207
|
+
- spec/loan_with_currency_and_validation_model_spec_helper.rb
|
205
208
|
- spec/loan_with_currency_model_spec_helper.rb
|
206
209
|
- spec/migration_factory_spec_helper.rb
|
207
210
|
- spec/simplecov_helper.rb
|
@@ -244,16 +247,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
244
247
|
version: '0'
|
245
248
|
segments:
|
246
249
|
- 0
|
247
|
-
hash:
|
250
|
+
hash: 4030965021580027687
|
248
251
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
249
252
|
none: false
|
250
253
|
requirements:
|
251
|
-
- - ! '
|
254
|
+
- - ! '>'
|
252
255
|
- !ruby/object:Gem::Version
|
253
|
-
version:
|
254
|
-
segments:
|
255
|
-
- 0
|
256
|
-
hash: -3822270686044656207
|
256
|
+
version: 1.3.1
|
257
257
|
requirements: []
|
258
258
|
rubyforge_project:
|
259
259
|
rubygems_version: 1.8.24
|
@@ -264,9 +264,11 @@ test_files:
|
|
264
264
|
- spec/active_record/currency_persistence_spec.rb
|
265
265
|
- spec/active_record/migration_spec.rb
|
266
266
|
- spec/active_record/money_dsl_spec.rb
|
267
|
+
- spec/active_record/validates_money_spec.rb
|
267
268
|
- spec/active_record_spec_helper.rb
|
268
269
|
- spec/configuration_spec.rb
|
269
270
|
- spec/loan_model_spec_helper.rb
|
271
|
+
- spec/loan_with_currency_and_validation_model_spec_helper.rb
|
270
272
|
- spec/loan_with_currency_model_spec_helper.rb
|
271
273
|
- spec/migration_factory_spec_helper.rb
|
272
274
|
- spec/simplecov_helper.rb
|