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.
@@ -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
@@ -1,3 +1,3 @@
1
1
  module EasyRailsMoney
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -6,147 +6,214 @@ if defined? ActiveRecord
6
6
 
7
7
  require 'active_record/schema_dumper'
8
8
 
9
- class CreateLoan < ActiveRecord::Migration
10
- def change
11
- suppress_messages do
12
- create_table :loans do |t|
13
- t.string :name
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
- class AddPrincipalToLoan < ActiveRecord::Migration
20
- def change
21
- suppress_messages do
22
- change_table :loans do |t|
23
- t.money :principal
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
- class CreateLoanWithPrincipal < ActiveRecord::Migration
30
- def change
31
- suppress_messages do
32
- create_table :loans do |t|
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
- class RemovePrincipalFromLoan < ActiveRecord::Migration
41
- def change
42
- suppress_messages do
43
- remove_money :loans, :principal
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
- class CreateLoanWithPrincipalUsingTableApi < ActiveRecord::Migration
49
- def change
50
- suppress_messages do
51
- create_table :loans do |t|
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
- class RemovePrincipalFromLoanUsingTableApi < ActiveRecord::Migration
60
- def change
61
- suppress_messages do
62
- change_table :loans do |t|
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
- class CreateLoanWithMultipleMoneyColumns < ActiveRecord::Migration
70
- def change
71
- suppress_messages do
72
- create_table :loans, force: true do |t|
73
- t.string :name
74
- t.money :principal
75
- t.money :repaid
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
- class CreateLoanWithSingleCurrencyColumnGivenLast < ActiveRecord::Migration
83
- def change
84
- suppress_messages do
85
- create_table :loans, force: true do |t|
86
- t.string :name
87
- t.money :principal
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
- class CreateLoanWithSingleCurrencyColumnGivenFirst < ActiveRecord::Migration
97
- def change
98
- suppress_messages do
99
- create_table :loans, force: true do |t|
100
- t.string :name
101
- t.currency
102
- t.money :principal
103
- t.money :repaid
104
- t.money :npa
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
- class CreateLoanWithSingleCurrencyColumnOrderDoesNotMatter < ActiveRecord::Migration
111
- def change
112
- suppress_messages do
113
- create_table :loans, force: true do |t|
114
- t.string :name
115
- t.money :principal
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
- class RemoveCurrencyFromLoan < ActiveRecord::Migration
125
- def change
126
- suppress_messages do
127
- change_table :loans, force: true do |t|
128
- t.remove_currency
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
- class AddSingleCurrencyToLoan < ActiveRecord::Migration
135
- def change
136
- suppress_messages do
137
- change_table :loans, force: true do |t|
138
- t.currency
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
- end
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 "migration" do
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 "schema_statements" do
196
- before(:each) do
197
- migrate CreateLoanWithPrincipal
198
- end
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
- describe "add_money" do
201
- it "creates integer column for money and a string column for currency" do
202
- expect(dump_schema).to eq schema_with_principal
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
- describe "remove_money" do
207
- it "remove integer column for money and a string column for currency" do
208
- expect { migrate RemovePrincipalFromLoan }.to change { dump_schema }.from(schema_with_principal).to(schema_with_only_name)
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
- context "table_statements" do
214
- before(:each) do
215
- migrate CreateLoanWithPrincipalUsingTableApi
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
- end
223
-
224
- describe "remove_money" do
225
- it "remove integer column for money and a string column for currency" do
226
- expect { migrate RemovePrincipalFromLoanUsingTableApi }.to change { dump_schema }.from(schema_with_principal).to(schema_with_only_name)
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
- context "single currency column", :single_currency do
232
- it "creates integer columns for money and a single string column for currency" do
233
- migrate CreateLoanWithSingleCurrencyColumnGivenLast
234
- expect(dump_schema).to eq schema_with_single_currency_column
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
- context "order does not matter" do
238
- it "creates integer columns for money and a single string column for currency even when currency column is given first" do
239
- migrate CreateLoanWithSingleCurrencyColumnGivenFirst
240
- expect(dump_schema).to eq schema_with_single_currency_column
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
- it "creates integer columns for money and a single string column for currency even when currency column is given in between" do
244
- migrate CreateLoanWithSingleCurrencyColumnOrderDoesNotMatter
245
- expect(dump_schema).to eq schema_with_single_currency_column
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
- it "can remove the currency column later" do
250
- migrate CreateLoanWithSingleCurrencyColumnGivenLast
251
- expect { migrate RemoveCurrencyFromLoan }.to change { dump_schema }.from(schema_with_single_currency_column).to(schema_with_multiple_currency_columns)
252
- end
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
- it "can add a single currrency column later" do
255
- migrate CreateLoanWithMultipleMoneyColumns
256
- expect { migrate AddSingleCurrencyToLoan }.to change { dump_schema }.from(schema_with_multiple_currency_columns).to(schema_with_single_currency_column)
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
- end
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
- end # describe "migration"
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