easy_rails_money 0.0.2 → 0.0.3
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 +1 -0
- data/CHANGELOG.md +22 -0
- data/README.md +139 -39
- data/Rakefile +9 -0
- data/easy_rails_money.gemspec +12 -1
- data/lib/easy_rails_money.rb +8 -0
- data/lib/easy_rails_money/active_record/migration/schema_statements.rb +91 -5
- data/lib/easy_rails_money/active_record/migration/table.rb +83 -18
- data/lib/easy_rails_money/active_record/migration/table_definition.rb +32 -2
- data/lib/easy_rails_money/version.rb +1 -1
- data/spec/active_record/migration_spec.rb +273 -139
- data/spec/configuration_spec.rb +1 -1
- data/spec/simplecov_helper.rb +8 -0
- data/spec/spec_helper.rb +1 -0
- data/vendor/cache/redcarpet-2.2.2.gem +0 -0
- data/vendor/cache/simplecov-0.7.1.gem +0 -0
- data/vendor/cache/simplecov-html-0.7.1.gem +0 -0
- data/vendor/cache/yard-0.8.5.2.gem +0 -0
- metadata +70 -8
@@ -3,12 +3,41 @@ module EasyRailsMoney
|
|
3
3
|
module Migration
|
4
4
|
module TableDefinition
|
5
5
|
# called for create_table
|
6
|
-
|
6
|
+
|
7
|
+
# Adds a common currency column
|
8
|
+
#
|
9
|
+
# Usually we create an currency column for each money
|
10
|
+
# columns. We can have multiple money columns in the same
|
11
|
+
# record, in which case we can have a single currency
|
12
|
+
# column. This helper creates that common curremcy column
|
13
|
+
#
|
14
|
+
# @return is not important and can change
|
15
|
+
#
|
16
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#remove_currency
|
7
17
|
def currency
|
8
18
|
remove_currency_columns
|
9
19
|
column :currency, :string
|
10
20
|
end
|
11
|
-
|
21
|
+
|
22
|
+
# Creates one or two columns to represent a Money object in the named table
|
23
|
+
#
|
24
|
+
# An integer column for storing Money in its base unit
|
25
|
+
# eg. cents for a Dollar denomination and a string for storing
|
26
|
+
# its currency name. Can think of it as a persisted or serialized
|
27
|
+
# Money object in the database. The integer column is suffixed
|
28
|
+
# with '_money' to aid in reflection ie. to find all money
|
29
|
+
# columns. Likewise the currency column is suffixed with '_currency'
|
30
|
+
# If does not create an individual currency column if a
|
31
|
+
# common currency column is defined
|
32
|
+
#
|
33
|
+
# @param column_names [Array|Symbol|String] List of money columns to add
|
34
|
+
# @return is not important and can change
|
35
|
+
#
|
36
|
+
# @note If we have defined a currency column for a record then only the integer column is defined.
|
37
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#add_money
|
38
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::Table#money
|
39
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::TableDefinition#currency
|
40
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#remove_money
|
12
41
|
def money(*column_names)
|
13
42
|
column_names.each do |name|
|
14
43
|
column "#{name}_money", :integer
|
@@ -18,6 +47,7 @@ module EasyRailsMoney
|
|
18
47
|
end
|
19
48
|
end
|
20
49
|
|
50
|
+
protected
|
21
51
|
def remove_currency_columns
|
22
52
|
columns.delete_if { |x| x.name =~ /_currency/ }
|
23
53
|
end
|
@@ -6,147 +6,214 @@ if defined? ActiveRecord
|
|
6
6
|
|
7
7
|
require 'active_record/schema_dumper'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
# migrations used in tests. our factories/fixtures
|
10
|
+
# their class names are the same if they are functionally
|
11
|
+
# equivalent, but are organized in different modules depending on
|
12
|
+
# whether it is implemented using
|
13
|
+
# schema_statements, create_table or change_table
|
14
|
+
module SchemaStatements
|
15
|
+
class CreateLoanAndMoney < ActiveRecord::Migration
|
16
|
+
def change
|
17
|
+
suppress_messages do
|
18
|
+
create_table :loans do |t|
|
19
|
+
t.string :name
|
20
|
+
end
|
21
|
+
add_money :loans, :principal
|
14
22
|
end
|
15
23
|
end
|
16
24
|
end
|
17
|
-
end
|
18
25
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
26
|
+
class CreateLoanWithCurrency < ActiveRecord::Migration
|
27
|
+
def change
|
28
|
+
suppress_messages do
|
29
|
+
create_table :loans do |t|
|
30
|
+
t.string :name
|
31
|
+
t.currency
|
32
|
+
end
|
33
|
+
add_money :loans, :principal, :repaid, :npa
|
24
34
|
end
|
25
35
|
end
|
26
36
|
end
|
27
|
-
end
|
28
37
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
t.string :name
|
38
|
+
class RemoveMoneyColumnsFromLoan < ActiveRecord::Migration
|
39
|
+
def change
|
40
|
+
suppress_messages do
|
41
|
+
remove_money :loans, :principal, :repaid, :npa
|
34
42
|
end
|
35
|
-
add_money :loans, :principal
|
36
43
|
end
|
37
44
|
end
|
38
|
-
end
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
class RemoveMoneyColumnsExceptPrincipalFromLoan < ActiveRecord::Migration
|
47
|
+
def change
|
48
|
+
suppress_messages do
|
49
|
+
remove_money :loans, :repaid, :npa
|
50
|
+
end
|
44
51
|
end
|
45
52
|
end
|
46
|
-
end
|
47
53
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
t.string :name
|
53
|
-
t.money :principal
|
54
|
+
class RemovePrincipalFromLoan < ActiveRecord::Migration
|
55
|
+
def change
|
56
|
+
suppress_messages do
|
57
|
+
remove_money :loans, :principal
|
54
58
|
end
|
55
59
|
end
|
56
60
|
end
|
57
|
-
end
|
58
61
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
t.remove_money :principal
|
62
|
+
class RemoveCurrencyFromLoan < ActiveRecord::Migration
|
63
|
+
def change
|
64
|
+
suppress_messages do
|
65
|
+
remove_currency :loans
|
64
66
|
end
|
65
67
|
end
|
66
68
|
end
|
67
|
-
end
|
69
|
+
end # module SchemaStatements
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
t.money :npa
|
71
|
+
module ChangeTable
|
72
|
+
class AddPrincipalToLoan < ActiveRecord::Migration
|
73
|
+
def change
|
74
|
+
suppress_messages do
|
75
|
+
change_table :loans do |t|
|
76
|
+
t.money :principal
|
77
|
+
end
|
77
78
|
end
|
78
79
|
end
|
79
80
|
end
|
80
|
-
end
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
t.money :repaid
|
89
|
-
t.money :npa
|
90
|
-
t.currency
|
82
|
+
class RemoveCurrencyFromLoan < ActiveRecord::Migration
|
83
|
+
def change
|
84
|
+
suppress_messages do
|
85
|
+
change_table :loans, force: true do |t|
|
86
|
+
t.remove_currency
|
87
|
+
end
|
91
88
|
end
|
92
89
|
end
|
93
90
|
end
|
94
|
-
end
|
95
91
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
92
|
+
class RemovePrincipalFromLoan < ActiveRecord::Migration
|
93
|
+
def change
|
94
|
+
suppress_messages do
|
95
|
+
change_table :loans do |t|
|
96
|
+
t.remove_money :principal
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class AddSingleCurrencyToLoan < ActiveRecord::Migration
|
103
|
+
def change
|
104
|
+
suppress_messages do
|
105
|
+
change_table :loans, force: true do |t|
|
106
|
+
t.currency
|
107
|
+
end
|
105
108
|
end
|
106
109
|
end
|
107
110
|
end
|
108
|
-
end
|
109
111
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
t.money :repaid
|
117
|
-
t.currency
|
118
|
-
t.money :npa
|
112
|
+
class RemoveMoneyColumnsFromLoan < ActiveRecord::Migration
|
113
|
+
def change
|
114
|
+
suppress_messages do
|
115
|
+
change_table :loans, force: true do |t|
|
116
|
+
t.remove_money :principal, :repaid, :npa
|
117
|
+
end
|
119
118
|
end
|
120
119
|
end
|
121
120
|
end
|
122
|
-
end
|
123
121
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
122
|
+
class RemoveMoneyColumnsExceptPrincipalFromLoan < ActiveRecord::Migration
|
123
|
+
def change
|
124
|
+
suppress_messages do
|
125
|
+
change_table :loans, force: true do |t|
|
126
|
+
t.remove_money :repaid, :npa
|
127
|
+
end
|
129
128
|
end
|
130
129
|
end
|
131
130
|
end
|
132
|
-
end
|
131
|
+
end # module ChangeTable
|
133
132
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
t
|
133
|
+
module CreateTableDefinition
|
134
|
+
class CreateLoan < ActiveRecord::Migration
|
135
|
+
def change
|
136
|
+
suppress_messages do
|
137
|
+
create_table :loans do |t|
|
138
|
+
t.string :name
|
139
|
+
end
|
139
140
|
end
|
140
141
|
end
|
141
142
|
end
|
142
|
-
|
143
|
+
|
144
|
+
class CreateLoanAndMoney < ActiveRecord::Migration
|
145
|
+
def change
|
146
|
+
suppress_messages do
|
147
|
+
create_table :loans do |t|
|
148
|
+
t.string :name
|
149
|
+
t.money :principal
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
class CreateLoanWithCurrency < ActiveRecord::Migration
|
156
|
+
def change
|
157
|
+
suppress_messages do
|
158
|
+
create_table :loans, force: true do |t|
|
159
|
+
t.string :name
|
160
|
+
t.money :principal
|
161
|
+
t.money :repaid
|
162
|
+
t.money :npa
|
163
|
+
t.currency
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
class CreateLoanWithoutCurrency < ActiveRecord::Migration
|
170
|
+
def change
|
171
|
+
suppress_messages do
|
172
|
+
create_table :loans, force: true do |t|
|
173
|
+
t.string :name
|
174
|
+
t.money :principal
|
175
|
+
t.money :repaid
|
176
|
+
t.money :npa
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
class CreateLoanWithCurrencySpecifiedFirst < ActiveRecord::Migration
|
183
|
+
def change
|
184
|
+
suppress_messages do
|
185
|
+
create_table :loans, force: true do |t|
|
186
|
+
t.string :name
|
187
|
+
t.currency
|
188
|
+
t.money :principal
|
189
|
+
t.money :repaid
|
190
|
+
t.money :npa
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
class CreateLoanWithCurrencySpecifiedInBetween < ActiveRecord::Migration
|
197
|
+
def change
|
198
|
+
suppress_messages do
|
199
|
+
create_table :loans, force: true do |t|
|
200
|
+
t.string :name
|
201
|
+
t.money :principal
|
202
|
+
t.money :repaid
|
203
|
+
t.currency
|
204
|
+
t.money :npa
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end # module CreateTableDefinition
|
143
210
|
|
144
211
|
# class Loan < ActiveRecord::Base
|
145
212
|
# attr_accessible :principal, :name
|
146
213
|
# # money :principal
|
147
214
|
# end
|
148
215
|
|
149
|
-
describe "
|
216
|
+
describe "Migrating Money columns" do
|
150
217
|
|
151
218
|
let(:schema_with_principal) do
|
152
219
|
<<-EOF.strip_spaces
|
@@ -158,6 +225,16 @@ if defined? ActiveRecord
|
|
158
225
|
EOF
|
159
226
|
end
|
160
227
|
|
228
|
+
let(:schema_with_principal_and_single_currency_column) do
|
229
|
+
<<-EOF.strip_spaces
|
230
|
+
create_table "loans", :force => true do |t|
|
231
|
+
t.string "name"
|
232
|
+
t.integer "principal_money"
|
233
|
+
t.string "currency"
|
234
|
+
end
|
235
|
+
EOF
|
236
|
+
end
|
237
|
+
|
161
238
|
let(:schema_with_only_name) do
|
162
239
|
<<-EOF.strip_spaces
|
163
240
|
create_table "loans", :force => true do |t|
|
@@ -192,75 +269,132 @@ EOF
|
|
192
269
|
EOF
|
193
270
|
end
|
194
271
|
|
195
|
-
context "
|
196
|
-
|
197
|
-
|
198
|
-
|
272
|
+
context "and testing schema statements", :schema_statements do
|
273
|
+
context "which have one currency column for each money column" do
|
274
|
+
before(:each) do
|
275
|
+
migrate SchemaStatements::CreateLoanAndMoney
|
276
|
+
end
|
199
277
|
|
200
|
-
|
201
|
-
|
202
|
-
|
278
|
+
describe "#add_money" do
|
279
|
+
it "creates two columns for each money attribute. one to store the lower denomination as an integer and the currency as a string" do
|
280
|
+
expect(dump_schema).to eq schema_with_principal
|
281
|
+
end
|
203
282
|
end
|
204
|
-
end
|
205
283
|
|
206
|
-
|
207
|
-
|
208
|
-
|
284
|
+
describe "#remove_money" do
|
285
|
+
it "drops two columns for each money attribute. one which stored the lower denomination as an integer and the currency as a string" do
|
286
|
+
expect { migrate SchemaStatements::RemovePrincipalFromLoan }.to change { dump_schema }.from(schema_with_principal).to(schema_with_only_name)
|
287
|
+
end
|
209
288
|
end
|
210
289
|
end
|
211
|
-
end
|
212
290
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
end
|
217
|
-
|
218
|
-
describe "add_money" do
|
219
|
-
it "creates integer column for money and a string column for currency" do
|
220
|
-
expect(dump_schema).to eq schema_with_principal
|
291
|
+
context "which has a single currency", :single_currency do
|
292
|
+
before(:each) do
|
293
|
+
migrate SchemaStatements::CreateLoanWithCurrency
|
221
294
|
end
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
295
|
+
|
296
|
+
describe "#add_money" do
|
297
|
+
it "creates one column for each money attribute, to store the lower denomination as an integer. currency is stored in a common column" do
|
298
|
+
expect(dump_schema).to eq schema_with_single_currency_column
|
299
|
+
end
|
227
300
|
end
|
228
|
-
end
|
229
|
-
end
|
230
301
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
end
|
302
|
+
describe "#remove_money" do
|
303
|
+
it "drops the money column for each money attribute and the common currency column as well", :fixme, :fixme_need_to_clear_table_cache do
|
304
|
+
expect { migrate SchemaStatements::RemoveMoneyColumnsFromLoan }.to change { dump_schema }.from(schema_with_single_currency_column).to(schema_with_only_name)
|
305
|
+
end
|
236
306
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
307
|
+
it "drops the money column for each money attribute but keeps the common currency column because some money columns still remain" do
|
308
|
+
expect { migrate SchemaStatements::RemoveMoneyColumnsExceptPrincipalFromLoan }.to change { dump_schema }.
|
309
|
+
from(schema_with_single_currency_column).
|
310
|
+
to(schema_with_principal_and_single_currency_column)
|
311
|
+
end
|
241
312
|
end
|
242
313
|
|
243
|
-
|
244
|
-
|
245
|
-
|
314
|
+
describe "#remove_currency" do
|
315
|
+
it "drops the common currency column and adds a currency columns to each of the existing money columns" do
|
316
|
+
expect { migrate SchemaStatements::RemoveCurrencyFromLoan }.to change { dump_schema }.from(schema_with_single_currency_column).to(schema_with_multiple_currency_columns)
|
317
|
+
end
|
318
|
+
|
319
|
+
pending "remove currency while side-by-side adding a money column"
|
246
320
|
end
|
247
321
|
end
|
322
|
+
end # context "schema_statements"
|
248
323
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
324
|
+
context "and testing table statements", :table_statements do
|
325
|
+
context "which have one currency column for each money column" do
|
326
|
+
before(:each) do
|
327
|
+
migrate CreateTableDefinition::CreateLoanAndMoney
|
328
|
+
end
|
329
|
+
|
330
|
+
describe "#add_money" do
|
331
|
+
it "creates two columns for each money attribute. one to store the lower denomination as an integer and the currency as a string" do
|
332
|
+
expect(dump_schema).to eq schema_with_principal
|
333
|
+
end
|
334
|
+
end
|
253
335
|
|
254
|
-
|
255
|
-
|
256
|
-
|
336
|
+
describe "#remove_money" do
|
337
|
+
it "drops two columns for each money attribute. one which stored the lower denomination as an integer and the currency as a string" do
|
338
|
+
expect { migrate ChangeTable::RemovePrincipalFromLoan }.to change { dump_schema }.from(schema_with_principal).to(schema_with_only_name)
|
339
|
+
end
|
340
|
+
end
|
257
341
|
end
|
258
|
-
|
342
|
+
|
343
|
+
context "which has a single currency", :single_currency do
|
344
|
+
describe "#add_money" do
|
345
|
+
context "and tests that order of statements does not matter" do
|
346
|
+
it "creates money and common currency cilumns when currency column is specified last" do
|
347
|
+
migrate CreateTableDefinition::CreateLoanWithCurrency
|
348
|
+
expect(dump_schema).to eq schema_with_single_currency_column
|
349
|
+
end
|
350
|
+
|
351
|
+
it "creates money and common currency cilumns when currency column is specified first" do
|
352
|
+
migrate CreateTableDefinition::CreateLoanWithCurrencySpecifiedFirst
|
353
|
+
expect(dump_schema).to eq schema_with_single_currency_column
|
354
|
+
end
|
355
|
+
|
356
|
+
it "creates money and common currency cilumns when currency column is specified in-between" do
|
357
|
+
migrate CreateTableDefinition::CreateLoanWithCurrencySpecifiedInBetween
|
358
|
+
expect(dump_schema).to eq schema_with_single_currency_column
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
describe "#remove_money" do
|
364
|
+
before(:each) do
|
365
|
+
migrate CreateTableDefinition::CreateLoanWithCurrency
|
366
|
+
end
|
367
|
+
|
368
|
+
it "drops the money column for each money attribute and the common currency column as well" do
|
369
|
+
expect { migrate ChangeTable::RemoveMoneyColumnsFromLoan }.to change { dump_schema }.from(schema_with_single_currency_column).to(schema_with_only_name)
|
370
|
+
end
|
371
|
+
|
372
|
+
it "drops the money column for each money attribute but keeps the common currency column because some money columns still remain" do
|
373
|
+
expect { migrate ChangeTable::RemoveMoneyColumnsExceptPrincipalFromLoan }.to change { dump_schema }.
|
374
|
+
from(schema_with_single_currency_column).
|
375
|
+
to(schema_with_principal_and_single_currency_column)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
describe "#remove_currency" do
|
380
|
+
it "drops the common currency column and adds a currency columns to each of the existing money columns" do
|
381
|
+
migrate CreateTableDefinition::CreateLoanWithCurrency
|
382
|
+
expect { migrate ChangeTable::RemoveCurrencyFromLoan }.to change { dump_schema }.from(schema_with_single_currency_column).to(schema_with_multiple_currency_columns)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
it "can add a single currrency column later" do
|
387
|
+
migrate CreateTableDefinition::CreateLoanWithoutCurrency
|
388
|
+
expect { migrate ChangeTable::AddSingleCurrencyToLoan }.to change { dump_schema }.from(schema_with_multiple_currency_columns).to(schema_with_single_currency_column)
|
389
|
+
end
|
390
|
+
end # context "which has a single currency"
|
391
|
+
end # context "and testing table statements"
|
259
392
|
|
260
393
|
it "can add a money column later" do
|
261
|
-
migrate CreateLoan
|
262
|
-
expect { migrate AddPrincipalToLoan }.to change { dump_schema }.from(schema_with_only_name).to(schema_with_principal)
|
394
|
+
migrate CreateTableDefinition::CreateLoan
|
395
|
+
expect { migrate ChangeTable::AddPrincipalToLoan }.to change { dump_schema }.from(schema_with_only_name).to(schema_with_principal)
|
263
396
|
end
|
264
397
|
|
265
|
-
|
398
|
+
pending "separate up and down migration methods. using add_money and remove_money"
|
399
|
+
end # describe "Migrating Money columns"
|
266
400
|
end # if defined? ActiveRecord
|