money_column 0.1.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.
- data/.gitignore +2 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +45 -0
- data/Guardfile +16 -0
- data/LICENSE +20 -0
- data/README.markdown +29 -0
- data/Rakefile +9 -0
- data/lib/money_column/stores_money.rb +43 -0
- data/lib/money_column.rb +11 -0
- data/money_column.gemspec +30 -0
- data/spec/money_column/money_column_spec.rb +50 -0
- data/spec/schema.rb +41 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +20 -0
- metadata +210 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
money_column (0.1.0)
|
5
|
+
activerecord (>= 2.3.14)
|
6
|
+
money (~> 2.2.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activerecord (2.3.14)
|
12
|
+
activesupport (= 2.3.14)
|
13
|
+
activesupport (2.3.14)
|
14
|
+
diff-lcs (1.1.3)
|
15
|
+
growl (1.0.3)
|
16
|
+
guard (0.8.8)
|
17
|
+
thor (~> 0.14.6)
|
18
|
+
guard-rspec (0.5.8)
|
19
|
+
guard (>= 0.8.4)
|
20
|
+
money (2.2.0)
|
21
|
+
rake (0.9.2.2)
|
22
|
+
rb-fsevent (0.4.3.1)
|
23
|
+
rspec (2.7.0)
|
24
|
+
rspec-core (~> 2.7.0)
|
25
|
+
rspec-expectations (~> 2.7.0)
|
26
|
+
rspec-mocks (~> 2.7.0)
|
27
|
+
rspec-core (2.7.1)
|
28
|
+
rspec-expectations (2.7.0)
|
29
|
+
diff-lcs (~> 1.1.2)
|
30
|
+
rspec-mocks (2.7.0)
|
31
|
+
sqlite3 (1.3.4)
|
32
|
+
thor (0.14.6)
|
33
|
+
|
34
|
+
PLATFORMS
|
35
|
+
ruby
|
36
|
+
|
37
|
+
DEPENDENCIES
|
38
|
+
activerecord (= 2.3.14)
|
39
|
+
growl (~> 1.0.3)
|
40
|
+
guard-rspec (~> 0.5.0)
|
41
|
+
money_column!
|
42
|
+
rake (~> 0.9.2)
|
43
|
+
rb-fsevent (~> 0.4.2)
|
44
|
+
rspec (~> 2.7.0)
|
45
|
+
sqlite3 (~> 1.3.4)
|
data/Guardfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Run me with:
|
2
|
+
#
|
3
|
+
# $ bundle exec guard
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rb-inotify'
|
7
|
+
require 'libnotify'
|
8
|
+
rescue LoadError
|
9
|
+
end
|
10
|
+
|
11
|
+
guard 'rspec', :all_on_start => false, :all_after_pass => false do
|
12
|
+
watch(%r{^spec/.+_spec\.rb})
|
13
|
+
watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
14
|
+
watch(%r{^spec/.+_spec\.rb})
|
15
|
+
end
|
16
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) Chargify
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
MoneyColumn [](http://travis-ci.org/chargify/money_column)
|
2
|
+
===========
|
3
|
+
|
4
|
+
A set of helper methods for working with money-based database columns.
|
5
|
+
|
6
|
+
## How it works
|
7
|
+
|
8
|
+
The money values are stored in the database in cents. The currency is not (necessarily) stored in the same table - instead, the currency is defined by a +currency+ method on the object instance.
|
9
|
+
|
10
|
+
Reading a money column returns a Money object (or nil, if :allow_nil is true), in the currency defined by the object instance.
|
11
|
+
|
12
|
+
Writing a money column assigns the cents-based database-backed attribute, and is assumed to be in the
|
13
|
+
currency of the target instance.
|
14
|
+
|
15
|
+
## Example
|
16
|
+
|
17
|
+
``` ruby
|
18
|
+
class Subscription < ActiveRecord::Base
|
19
|
+
belongs_to :site
|
20
|
+
|
21
|
+
stores_money :balance
|
22
|
+
|
23
|
+
def currency
|
24
|
+
site.currency
|
25
|
+
end
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
In this example, +balance+ provides a Money-based interface to the underlying +balance_in_cents+ database column. The currency is delegated to the site.
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module MoneyColumn
|
2
|
+
module StoresMoney
|
3
|
+
def self.included(klass)
|
4
|
+
klass.send(:extend, ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def stores_money(money_name, options = {})
|
9
|
+
options.reverse_merge!({
|
10
|
+
:cents_column => "#{money_name}_in_cents",
|
11
|
+
:allow_nil => true
|
12
|
+
})
|
13
|
+
|
14
|
+
class_eval <<-EOV
|
15
|
+
def #{money_name}
|
16
|
+
cents = send('#{options[:cents_column]}')
|
17
|
+
|
18
|
+
if !#{options[:allow_nil]}
|
19
|
+
cents ||= 0
|
20
|
+
end
|
21
|
+
|
22
|
+
if cents.blank?
|
23
|
+
nil
|
24
|
+
else
|
25
|
+
my_currency = self.respond_to?(:currency) ? currency : ::Money.default_currency
|
26
|
+
Money.new(cents, my_currency)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def #{money_name}=(amount)
|
31
|
+
self.#{options[:cents_column]} = if amount.blank?
|
32
|
+
nil
|
33
|
+
else
|
34
|
+
amount.to_money.cents
|
35
|
+
end
|
36
|
+
end
|
37
|
+
EOV
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
ActiveRecord::Base.send :include, MoneyColumn::StoresMoney
|
data/lib/money_column.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'money'
|
3
|
+
require 'money_column/stores_money'
|
4
|
+
|
5
|
+
# FREEDOM PATCH - Since a money column might validly return nil,
|
6
|
+
# let's allow +format+ to be called on nil and just return nil as a string
|
7
|
+
NilClass.class_eval do
|
8
|
+
def format
|
9
|
+
nil.to_s
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.specification_version = 3 if s.respond_to? :specification_version=
|
3
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
4
|
+
s.rubygems_version = '1.3.7'
|
5
|
+
|
6
|
+
s.name = 'money_column'
|
7
|
+
s.version = '0.1.0'
|
8
|
+
s.date = '2011-11-30'
|
9
|
+
s.summary = 'A set of helper methods for working with money-based database columns.'
|
10
|
+
s.description = 'A set of helper methods for working with money-based database columns.'
|
11
|
+
s.authors = ["Michael Klett"]
|
12
|
+
s.email = 'support@chargify.com'
|
13
|
+
s.homepage = 'http://github.com/chargify/money_column'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.require_paths = %w[lib]
|
18
|
+
|
19
|
+
# Runtime Dependencies
|
20
|
+
s.add_runtime_dependency('activerecord', '>= 2.3.14')
|
21
|
+
s.add_runtime_dependency('money', '~> 2.2.0')
|
22
|
+
|
23
|
+
# Development Dependencies
|
24
|
+
s.add_development_dependency('sqlite3', '~> 1.3.4')
|
25
|
+
s.add_development_dependency('rake', '~> 0.9.2')
|
26
|
+
s.add_development_dependency('rspec', '~> 2.7.0')
|
27
|
+
s.add_development_dependency('guard-rspec', '~> 0.5.0')
|
28
|
+
s.add_development_dependency('growl', '~> 1.0.3')
|
29
|
+
s.add_development_dependency('rb-fsevent', '~> 0.4.2')
|
30
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "MoneyColumn" do
|
4
|
+
describe "setter method" do
|
5
|
+
it "should pass on money values" do
|
6
|
+
MoneyExample.new(:amount => 1.to_money).amount.should == 1.to_money
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should convert string values to money objects" do
|
10
|
+
MoneyExample.new(:amount => '2').amount.should == 2.to_money
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should convert to money objects in the correct currency automatically" do
|
14
|
+
MoneyExampleWithNonDefaultCurrency.new(:amount => '4').amount.should == Money.new(400, 'GBP')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should convert numeric values to money objects" do
|
18
|
+
MoneyExample.new(:amount => 3).amount.should == 3.to_money
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "when nil is allowed" do
|
22
|
+
it "should treat blank values as nil" do
|
23
|
+
MoneyExample.new(:amount => '').amount.should be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "when nil isn't allowed" do
|
28
|
+
it "should treat blank values as $0" do
|
29
|
+
MoneyExampleThatDoesNotAllowNil.new(:amount => '').amount.should == Money.new(0, 'USD')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should allow existing amounts to be set to nil with a blank value" do
|
34
|
+
me = MoneyExample.new(:amount => 500.to_money)
|
35
|
+
me.update_attribute :amount, ''
|
36
|
+
me.reload
|
37
|
+
me.amount.should be_nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "declaring a money field" do
|
42
|
+
it "should allow the field to be declared with a different cents field" do
|
43
|
+
me = MoneyExampleWithSpecifiedColumnName.create!(:amt => 5.to_money)
|
44
|
+
me.amt.should == 5.to_money
|
45
|
+
me.reload.amt.should == 5.to_money
|
46
|
+
me.amount_in_cents.should == 5.to_money.cents
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/spec/schema.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
ActiveRecord::Schema.define(:version => 0) do
|
2
|
+
create_table :money_examples, :force => true do |t|
|
3
|
+
t.integer :amount_in_cents
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class MoneyExample < ActiveRecord::Base
|
8
|
+
stores_money :amount
|
9
|
+
end
|
10
|
+
|
11
|
+
class MoneyExampleWithCurrency < ActiveRecord::Base
|
12
|
+
set_table_name "money_examples"
|
13
|
+
|
14
|
+
stores_money :amount
|
15
|
+
|
16
|
+
def currency
|
17
|
+
::Money.default_currency
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class MoneyExampleWithNonDefaultCurrency < ActiveRecord::Base
|
22
|
+
set_table_name "money_examples"
|
23
|
+
|
24
|
+
stores_money :amount
|
25
|
+
|
26
|
+
def currency
|
27
|
+
"GBP"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class MoneyExampleWithSpecifiedColumnName < ActiveRecord::Base
|
32
|
+
set_table_name "money_examples"
|
33
|
+
|
34
|
+
stores_money :amt, :cents_column => "amount_in_cents"
|
35
|
+
end
|
36
|
+
|
37
|
+
class MoneyExampleThatDoesNotAllowNil < ActiveRecord::Base
|
38
|
+
set_table_name "money_examples"
|
39
|
+
|
40
|
+
stores_money :amount, :allow_nil => false
|
41
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
$:.unshift File.expand_path('../lib', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'money_column'
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
config.filter_run :focused => true
|
8
|
+
config.run_all_when_everything_filtered = true
|
9
|
+
config.alias_example_to :fit, :focused => true
|
10
|
+
config.color_enabled = true
|
11
|
+
end
|
12
|
+
|
13
|
+
ActiveRecord::Base.configurations = {'sqlite3' => {:adapter => 'sqlite3', :database => ':memory:'}}
|
14
|
+
ActiveRecord::Base.establish_connection('sqlite3')
|
15
|
+
|
16
|
+
ActiveRecord::Base.logger = Logger.new(STDERR)
|
17
|
+
ActiveRecord::Base.logger.level = Logger::WARN
|
18
|
+
|
19
|
+
# Load test database schema
|
20
|
+
load File.dirname(__FILE__) + "/schema.rb"
|
metadata
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: money_column
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Michael Klett
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-11-30 00:00:00 -05:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: activerecord
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 31
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 3
|
33
|
+
- 14
|
34
|
+
version: 2.3.14
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: money
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 7
|
46
|
+
segments:
|
47
|
+
- 2
|
48
|
+
- 2
|
49
|
+
- 0
|
50
|
+
version: 2.2.0
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: sqlite3
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 19
|
62
|
+
segments:
|
63
|
+
- 1
|
64
|
+
- 3
|
65
|
+
- 4
|
66
|
+
version: 1.3.4
|
67
|
+
type: :development
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 63
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
- 9
|
81
|
+
- 2
|
82
|
+
version: 0.9.2
|
83
|
+
type: :development
|
84
|
+
version_requirements: *id004
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: rspec
|
87
|
+
prerelease: false
|
88
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 19
|
94
|
+
segments:
|
95
|
+
- 2
|
96
|
+
- 7
|
97
|
+
- 0
|
98
|
+
version: 2.7.0
|
99
|
+
type: :development
|
100
|
+
version_requirements: *id005
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: guard-rspec
|
103
|
+
prerelease: false
|
104
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: 11
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
- 5
|
113
|
+
- 0
|
114
|
+
version: 0.5.0
|
115
|
+
type: :development
|
116
|
+
version_requirements: *id006
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: growl
|
119
|
+
prerelease: false
|
120
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
hash: 17
|
126
|
+
segments:
|
127
|
+
- 1
|
128
|
+
- 0
|
129
|
+
- 3
|
130
|
+
version: 1.0.3
|
131
|
+
type: :development
|
132
|
+
version_requirements: *id007
|
133
|
+
- !ruby/object:Gem::Dependency
|
134
|
+
name: rb-fsevent
|
135
|
+
prerelease: false
|
136
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ~>
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
hash: 11
|
142
|
+
segments:
|
143
|
+
- 0
|
144
|
+
- 4
|
145
|
+
- 2
|
146
|
+
version: 0.4.2
|
147
|
+
type: :development
|
148
|
+
version_requirements: *id008
|
149
|
+
description: A set of helper methods for working with money-based database columns.
|
150
|
+
email: support@chargify.com
|
151
|
+
executables: []
|
152
|
+
|
153
|
+
extensions: []
|
154
|
+
|
155
|
+
extra_rdoc_files: []
|
156
|
+
|
157
|
+
files:
|
158
|
+
- .gitignore
|
159
|
+
- Gemfile
|
160
|
+
- Gemfile.lock
|
161
|
+
- Guardfile
|
162
|
+
- LICENSE
|
163
|
+
- README.markdown
|
164
|
+
- Rakefile
|
165
|
+
- lib/money_column.rb
|
166
|
+
- lib/money_column/stores_money.rb
|
167
|
+
- money_column.gemspec
|
168
|
+
- spec/money_column/money_column_spec.rb
|
169
|
+
- spec/schema.rb
|
170
|
+
- spec/spec.opts
|
171
|
+
- spec/spec_helper.rb
|
172
|
+
has_rdoc: true
|
173
|
+
homepage: http://github.com/chargify/money_column
|
174
|
+
licenses: []
|
175
|
+
|
176
|
+
post_install_message:
|
177
|
+
rdoc_options: []
|
178
|
+
|
179
|
+
require_paths:
|
180
|
+
- lib
|
181
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
182
|
+
none: false
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
hash: 3
|
187
|
+
segments:
|
188
|
+
- 0
|
189
|
+
version: "0"
|
190
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
191
|
+
none: false
|
192
|
+
requirements:
|
193
|
+
- - ">="
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
hash: 3
|
196
|
+
segments:
|
197
|
+
- 0
|
198
|
+
version: "0"
|
199
|
+
requirements: []
|
200
|
+
|
201
|
+
rubyforge_project:
|
202
|
+
rubygems_version: 1.6.2
|
203
|
+
signing_key:
|
204
|
+
specification_version: 3
|
205
|
+
summary: A set of helper methods for working with money-based database columns.
|
206
|
+
test_files:
|
207
|
+
- spec/money_column/money_column_spec.rb
|
208
|
+
- spec/schema.rb
|
209
|
+
- spec/spec.opts
|
210
|
+
- spec/spec_helper.rb
|