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
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## 0.0.1
|
4
|
+
- Add a README listing the rationale and rough draft of the migration
|
5
|
+
DSL to be implemented
|
6
|
+
- Added migration DSL to add two columns to persist a money object.
|
7
|
+
An Interger column to persist the money amount and a String column
|
8
|
+
to persist the currency name
|
9
|
+
|
10
|
+
## 0.0.2
|
11
|
+
- Modify migration DSL to support multiple money amount columns and a
|
12
|
+
single currency column
|
13
|
+
- add travis, codeclimate and gemnasium gem-dependency badges
|
14
|
+
- has a dependency on ActiveRecord and removed the dependency on Rails
|
15
|
+
|
16
|
+
## 0.0.3
|
17
|
+
- add missing cases for supporting a single currency
|
18
|
+
- refactor tests
|
19
|
+
- add simplecov coverage report
|
20
|
+
- Add yard docs and update README
|
21
|
+
|
22
|
+
|
data/README.md
CHANGED
@@ -2,14 +2,20 @@
|
|
2
2
|
[](https://gemnasium.com/deepak/easy_rails_money)
|
3
3
|
[](https://codeclimate.com/github/deepak/easy_rails_money)
|
4
4
|
|
5
|
-
### Under Development
|
5
|
+
### Under Development
|
6
|
+
|
7
|
+
The migration helpers are functionally complete.
|
8
|
+
Working on integrating with Rails' ActiveModel
|
6
9
|
|
7
10
|
# EasyRailsMoney
|
8
11
|
|
9
|
-
|
12
|
+
> “Young people, nowadays, imagine that money is everything.
|
13
|
+
>
|
14
|
+
> Yes, murmured Lord Henry, settling his button-hole in his coat;
|
15
|
+
> and when they grow older they know it.”
|
16
|
+
> ― Oscar Wilde, The Picture of Dorian Gray and Other Writings
|
10
17
|
|
11
|
-
|
12
|
-
object
|
18
|
+
This library provides integration of [money](http://github.com/Rubymoney/money) gem with [Rails](https://github.com/rails/rails).
|
13
19
|
|
14
20
|
[money-rails](https://github.com/RubyMoney/money-rails) is much more
|
15
21
|
popular and full-featured. Definately try it out. I have actually
|
@@ -19,10 +25,37 @@ I have tried to create a simpler version of [money-rails](https://github.com/Rub
|
|
19
25
|
With a better API and database schema, in my opinion
|
20
26
|
I created this project to scratch my itch.
|
21
27
|
|
22
|
-
|
23
|
-
|
28
|
+
Please open a new issue [in the github project issues tracker](http://github.com/deepak/easy_rails_money/issues). You are also
|
29
|
+
more than welcome to contribute to the project :-)
|
30
|
+
|
31
|
+
## Credits
|
32
|
+
|
33
|
+
Have stolen lots of code from [money-rails](https://github.com/RubyMoney/money-rails)
|
34
|
+
But database schema, API and tests are written from scratch
|
35
|
+
|
36
|
+
## Installation
|
37
|
+
|
38
|
+
Add this line to your application's Gemfile:
|
39
|
+
|
40
|
+
gem 'easy_rails_money'
|
41
|
+
|
42
|
+
And then execute:
|
43
|
+
|
44
|
+
$ bundle
|
45
|
+
|
46
|
+
Or install it yourself as:
|
47
|
+
|
48
|
+
$ gem install easy_rails_money
|
49
|
+
|
50
|
+
## Contributing
|
51
|
+
|
52
|
+
1. Fork it
|
53
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
54
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
55
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
56
|
+
5. Create new Pull Request
|
24
57
|
|
25
|
-
##
|
58
|
+
## Rationale
|
26
59
|
|
27
60
|
Let us say you want to store a Rupee Money object in the database
|
28
61
|
|
@@ -30,6 +63,7 @@ Let us say you want to store a Rupee Money object in the database
|
|
30
63
|
principal = Money.new(100, "inr")
|
31
64
|
```
|
32
65
|
|
66
|
+
To serialize the values in the database
|
33
67
|
Option 1:
|
34
68
|
```ruby
|
35
69
|
class CreateLoan < ActiveRecord::Migration
|
@@ -58,8 +92,12 @@ Note that we are storing the base unit in the database. If the amount
|
|
58
92
|
is in dollars we store in cents or if the amount is in Indian Rupees
|
59
93
|
we store in paise and so on. This is done because FLoats do not have a
|
60
94
|
accurate representation but Integers do. Can store BigDecimal as well
|
61
|
-
but it is slower. This is why the Money gem stores amounts as integer
|
95
|
+
but it is slower. This is why the Money gem stores amounts as integer
|
96
|
+
|
62
97
|
Watch [Rubyconf 2011 Float-is-legacy](http://www.confreaks.com/videos/698-rubyconf2011-float-is-legacy) for more details
|
98
|
+
and read [What Every Computer Scientist Should Know About
|
99
|
+
Floating-Point Arithmetic, by David Goldberg, published in March,
|
100
|
+
1991](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)
|
63
101
|
|
64
102
|
We have encoded the currency in the column name. I like it because
|
65
103
|
there is no need to define another column and it is simple. But the
|
@@ -114,56 +152,118 @@ end
|
|
114
152
|
It might be possible that we set a currency once for the whole app and
|
115
153
|
never change it. But this seems like a nice tradeoff api-wise
|
116
154
|
|
117
|
-
|
118
|
-
1. currency is stored as a string. Integer might be better for storing in the database
|
119
|
-
2. store a snapshot of the exchange rate as well when the record was
|
120
|
-
inserted or if we want to "freeze" the exchange rate per-record
|
155
|
+
## Usage
|
121
156
|
|
122
|
-
|
157
|
+
### ActiveRecord
|
123
158
|
|
124
|
-
|
159
|
+
Only ActiveRecord is supported for now. And has been tested on
|
160
|
+
ActiveRecord 3.x
|
125
161
|
|
126
|
-
|
162
|
+
#### Migration helpers
|
127
163
|
|
128
|
-
|
164
|
+
If you want to create a table which has some money columns, then you can use the ```money``` migration helper
|
129
165
|
|
130
|
-
|
166
|
+
```ruby
|
167
|
+
class CreateLoanWithCurrency < ActiveRecord::Migration
|
168
|
+
def change
|
169
|
+
create_table :loans, force: true do |t|
|
170
|
+
t.string :name
|
171
|
+
t.money :principal
|
172
|
+
t.money :repaid
|
173
|
+
t.money :npa
|
174
|
+
t.currency
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
```
|
131
179
|
|
132
|
-
|
180
|
+
If you want to add a money column to an existing table then you can
|
181
|
+
again use the ```money``` migration helper
|
133
182
|
|
134
|
-
|
183
|
+
```ruby
|
184
|
+
class AddPrincipalToLoan < ActiveRecord::Migration
|
185
|
+
def change
|
186
|
+
change_table :loans do |t|
|
187
|
+
t.money :principal
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
```
|
135
192
|
|
136
|
-
|
193
|
+
Another option is to use ```add_money``` migration helper
|
194
|
+
It is a different DSL style, similar to ```create_table```
|
137
195
|
|
138
|
-
|
196
|
+
```ruby
|
197
|
+
class AddPrincipalToLoan < ActiveRecord::Migration
|
198
|
+
def up
|
199
|
+
add_money :loans, :principal, :repaid, :npa
|
200
|
+
end
|
139
201
|
|
140
|
-
|
202
|
+
def down
|
203
|
+
remove_money :loans, :principal, :repaid, :npa
|
204
|
+
end
|
205
|
+
end
|
206
|
+
```
|
141
207
|
|
142
|
-
|
208
|
+
```add_money``` helper is revertable, so you may use it inside ```change``` migrations.
|
209
|
+
If you writing separate ```up``` and ```down``` methods, you may use
|
210
|
+
the ```remove_money``` migration helper.
|
143
211
|
|
144
|
-
|
212
|
+
The above statements for ```money``` and ```add_money``` will create
|
213
|
+
two columns. An integer column to store the lower denomination as an
|
214
|
+
integer and a string column to store the currency name.
|
145
215
|
|
146
|
-
```
|
147
|
-
|
148
|
-
|
149
|
-
|
216
|
+
eg. if we say ```add_money :loans, :principal``` Then the following two
|
217
|
+
columns will be created:
|
218
|
+
1. integer column called ```principal_money```
|
219
|
+
2. string column called ```principal_currency```
|
150
220
|
|
151
|
-
|
221
|
+
If we want to store ```$ 100``` in this column then:
|
222
|
+
1. column ```principal_money``` will contain the unit in the lower denomination
|
223
|
+
ie. cents in this case. So for ```$100``` it will store ```100 * 100 => 100_000 cents```
|
224
|
+
2. column ```principal_currency``` will store the currency name ie. ```usd```
|
152
225
|
|
153
|
-
|
154
|
-
|
226
|
+
Both the amount and currency is needed to create a ```Money``` object
|
227
|
+
|
228
|
+
Now if we have multiple money columns, then you can choose to have a
|
229
|
+
single currency column
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
class CreateLoanWithCurrency < ActiveRecord::Migration
|
233
|
+
def change
|
234
|
+
create_table :loans, force: true do |t|
|
235
|
+
t.string :name
|
236
|
+
t.money :principal
|
237
|
+
t.money :repaid
|
238
|
+
t.money :npa
|
239
|
+
t.currency
|
155
240
|
end
|
156
241
|
end
|
157
242
|
end
|
158
243
|
```
|
159
244
|
|
160
|
-
|
161
|
-
|
245
|
+
This will create a single column for currency:
|
246
|
+
1. It creates three columns for each of the money columns
|
247
|
+
```principal_money```, ```repaid_money``` and ```npa_money```
|
248
|
+
2. note that it does not create a currency column for each of the
|
249
|
+
money columns. But a common currency column is created.
|
250
|
+
It is boringly enough called ```currency```
|
162
251
|
|
163
|
-
|
252
|
+
Note that columns are prefixed with ```_money``` and ```_currency```
|
253
|
+
And the common currency column is called ```currency```.
|
164
254
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
255
|
+
It is used to reflect on the database schema ie. to find out the
|
256
|
+
money and currency columns defined.
|
257
|
+
Right now, none of these choices are customizable.
|
258
|
+
|
259
|
+
## TODO's
|
260
|
+
1. Proof-read docs
|
261
|
+
2. currency is stored as a string. Integer might be better for storing in the database
|
262
|
+
3. store a snapshot of the exchange rate as well when the record was
|
263
|
+
inserted or if we want to "freeze" the exchange rate per-record
|
264
|
+
4. specs for migration test the same thing in multiple ways. have a
|
265
|
+
spec helper
|
266
|
+
5. add Gemfil to test on ActiveRecord 4.x ie. with Rails4 . Add to travis.yml as well
|
267
|
+
6. configure the ```_money``` and ```_currency``` prefix and the name
|
268
|
+
of the common ```currency``` column
|
269
|
+
7. check specs tagged as "fixme"
|
data/Rakefile
CHANGED
@@ -5,3 +5,12 @@ RSpec::Core::RakeTask.new('spec')
|
|
5
5
|
|
6
6
|
# If you want to make this the default task
|
7
7
|
task :default => :spec
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'yard'
|
11
|
+
YARD::Rake::YardocTask.new do |t|
|
12
|
+
t.files = ['lib/**/*.rb'] # optional
|
13
|
+
t.options = ['--one-file']
|
14
|
+
end
|
15
|
+
rescue LoadError
|
16
|
+
end
|
data/easy_rails_money.gemspec
CHANGED
@@ -21,8 +21,19 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.add_dependency "activesupport", "~> 3.2"
|
22
22
|
|
23
23
|
gem.add_development_dependency "rake", "~> 10.0.4"
|
24
|
+
|
25
|
+
# for running tests
|
24
26
|
gem.add_development_dependency "rspec", "~> 2.12"
|
25
|
-
|
27
|
+
# we use an in-memory sqlite database for speed
|
26
28
|
gem.add_development_dependency "sqlite3", "~> 1.3.7"
|
29
|
+
# testing against the ActiveRecord interface
|
30
|
+
gem.add_development_dependency "activerecord", "~> 3.2"
|
31
|
+
|
27
32
|
gem.add_development_dependency "debugger", "~> 1.5.0"
|
33
|
+
gem.add_development_dependency "simplecov", "~> 0.7.1"
|
34
|
+
|
35
|
+
# for generating docs
|
36
|
+
gem.add_development_dependency "yard", "~> 0.8.5.2"
|
37
|
+
# needed by YARD to read markdown files
|
38
|
+
gem.add_development_dependency "redcarpet", "~> 2.2.2"
|
28
39
|
end
|
data/lib/easy_rails_money.rb
CHANGED
@@ -1,7 +1,15 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
1
3
|
require "money"
|
2
4
|
require "easy_rails_money/version"
|
3
5
|
require "easy_rails_money/configuration"
|
4
6
|
|
7
|
+
# @author Deepak Kannan
|
8
|
+
# “Young people, nowadays, imagine that money is everything.
|
9
|
+
#
|
10
|
+
# Yes, murmured Lord Henry, settling his button-hole in his coat; and when they grow older they know it.”
|
11
|
+
# ― Oscar Wilde, The Picture of Dorian Gray and Other Writings
|
12
|
+
# This library provides integration of [money](http://github.com/Rubymoney/money) gem with [Rails](https://github.com/rails/rails).
|
5
13
|
module EasyRailsMoney
|
6
14
|
extend Configuration
|
7
15
|
end
|
@@ -2,18 +2,104 @@ module EasyRailsMoney
|
|
2
2
|
module ActiveRecord
|
3
3
|
module Migration
|
4
4
|
module SchemaStatements
|
5
|
-
|
6
|
-
|
5
|
+
# Creates one or two columns to represent a Money object in the named table
|
6
|
+
#
|
7
|
+
# An integer column for storing Money in its base unit
|
8
|
+
# eg. cents for a Dollar denomination and a string for storing
|
9
|
+
# its currency name. Can think of it as a persisted or serialized
|
10
|
+
# Money object in the database. The integer column is suffixed
|
11
|
+
# with '_money' to aid in reflection ie. to find all money
|
12
|
+
# columns. Likewise the currency column is suffixed with '_currency'
|
13
|
+
# If does not create an individual currency column if a
|
14
|
+
# common currency column is defined
|
15
|
+
#
|
16
|
+
# @param table_name [Symbol|String]
|
17
|
+
# @param column_names [Array|Symbol|String] List of money columns to add
|
18
|
+
# @return is not important and can change
|
19
|
+
#
|
20
|
+
# @note If we have defined a currency column for a record then only the integer column is defined.
|
21
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::TableDefinition#money
|
22
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::Table#money
|
23
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::TableDefinition#currency
|
24
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#remove_money
|
25
|
+
def add_money table_name, *column_names
|
26
|
+
column_names.each do |name|
|
7
27
|
add_column table_name, "#{name}_money", :integer
|
8
|
-
add_column table_name, "#{name}_currency", :string
|
28
|
+
add_column table_name, "#{name}_currency", :string unless has_currency_column?(table_name)
|
9
29
|
end
|
10
30
|
end
|
11
31
|
|
12
|
-
|
13
|
-
|
32
|
+
# Removes the columns which represent the Money object
|
33
|
+
#
|
34
|
+
# Removes the two columns added by add_money. The money amount and
|
35
|
+
# the currency column. If there are no remaining money amount columns
|
36
|
+
# and a common currency column exists. then it is also removed
|
37
|
+
#
|
38
|
+
# @param table_name [Symbol|String]
|
39
|
+
# @param column_names [Array|Symbol|String] List of money columns to remove
|
40
|
+
# @return is not important and can change
|
41
|
+
# @note If we have defined a currency column for a record then currency column is removed only if no other money column are there
|
42
|
+
#
|
43
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::Table#remove_money
|
44
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#add_money
|
45
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::TableDefinition#currency
|
46
|
+
# @note multiple remove_money calls are not supported in one migration. because at this point the schema is different from the migration defined
|
47
|
+
def remove_money table_name, *column_names
|
48
|
+
column_names.each do |name|
|
14
49
|
remove_column table_name, "#{name}_money"
|
15
50
|
remove_column table_name, "#{name}_currency"
|
16
51
|
end
|
52
|
+
remove_currency table_name unless has_money_columns?(table_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Removes the common currency column
|
56
|
+
#
|
57
|
+
# Usually we create an currency column for each money
|
58
|
+
# columns. We can have multiple money columns in the same
|
59
|
+
# record, in which case we can have a single currency
|
60
|
+
# column. This helper removes that common curremcy column. For
|
61
|
+
# the existing money column it adds back their currency
|
62
|
+
# columns as well. It reflects on the database schema by
|
63
|
+
# looking at the column name. By convention the money amount
|
64
|
+
# column is prefixed by '_money' and the currency column by '_currency'
|
65
|
+
#
|
66
|
+
# @param table_name [Symbol|String]
|
67
|
+
#
|
68
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::Table#remove_currency
|
69
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#remove_money
|
70
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::TableDefinition#currency
|
71
|
+
def remove_currency table_name
|
72
|
+
remove_column table_name, :currency
|
73
|
+
money_columns(table_name) do |money_column|
|
74
|
+
add_column table_name, "#{money_column}_currency", :string
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
protected
|
79
|
+
def has_currency_column? table_name
|
80
|
+
connection.schema_cache.clear_table_cache! table_name
|
81
|
+
connection.schema_cache.columns[table_name].select {|x| x.name == "currency" }.any?
|
82
|
+
end
|
83
|
+
|
84
|
+
def money_columns table_name
|
85
|
+
# FIXME: see specs tagged
|
86
|
+
# fixme_need_to_clear_table_cache. for that test needed to
|
87
|
+
# clear the cache
|
88
|
+
connection.schema_cache.clear_table_cache! table_name
|
89
|
+
connection.schema_cache.columns[table_name].select { |col|
|
90
|
+
col.name =~ /_money/
|
91
|
+
}.map { |col|
|
92
|
+
name = col.name.match(/(.+)_money/)[1]
|
93
|
+
if block_given?
|
94
|
+
yield name
|
95
|
+
else
|
96
|
+
name
|
97
|
+
end
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
def has_money_columns? table_name
|
102
|
+
money_columns(table_name).any?
|
17
103
|
end
|
18
104
|
end
|
19
105
|
end
|
@@ -5,27 +5,80 @@ module EasyRailsMoney
|
|
5
5
|
# called for change_table
|
6
6
|
# currency and #money defined in TableDefinition
|
7
7
|
|
8
|
+
# Creates one or two columns to represent a Money object in the named table
|
9
|
+
#
|
10
|
+
# An integer column for storing Money in its base unit
|
11
|
+
# eg. cents for a Dollar denomination and a string for storing
|
12
|
+
# its currency name. Can think of it as a persisted or serialized
|
13
|
+
# Money object in the database. The integer column is suffixed
|
14
|
+
# with '_money' to aid in reflection ie. to find all money
|
15
|
+
# columns. Likewise the currency column is suffixed with '_currency'
|
16
|
+
# If does not create an individual currency column if a
|
17
|
+
# common currency column is defined
|
18
|
+
#
|
19
|
+
# @param column_names [Array|Symbol|String] List of money columns to add
|
20
|
+
# @return is not important and can change
|
21
|
+
#
|
22
|
+
# @note If we have defined a currency column for a record then only the integer column is defined.
|
23
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#add_money
|
24
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::TableDefinition#money
|
25
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::TableDefinition#currency
|
26
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#remove_money
|
8
27
|
def money(*column_names)
|
9
28
|
column_names.each do |name|
|
10
|
-
column "#{name}_money",
|
11
|
-
|
12
|
-
column "#{name}_currency", :string
|
13
|
-
end
|
29
|
+
column "#{name}_money", :integer
|
30
|
+
column "#{name}_currency", :string unless has_currency_column?
|
14
31
|
end
|
15
32
|
end
|
16
33
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
34
|
+
# Removes the columns which represent the Money object
|
35
|
+
#
|
36
|
+
# Removes the two columns added by money. The money amount and
|
37
|
+
# the currency column. If there are no remaining money amount columns
|
38
|
+
# and a common currency column exists. then it is also removed
|
39
|
+
#
|
40
|
+
# @param column_names [Array|Symbol|String] List of money columns to remove
|
41
|
+
# @return is not important and can change
|
42
|
+
#
|
43
|
+
# @note If we have defined a currency column for a record then currency column is removed only if no other money column are there
|
44
|
+
#
|
45
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#remove_money
|
46
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#add_money
|
47
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::TableDefinition#currency
|
48
|
+
# @note multiple remove_money calls are not supported in one migration. because at this point the schema is different from the migration defined
|
22
49
|
def remove_money(*column_names)
|
23
50
|
column_names.each do |name|
|
24
51
|
remove "#{name}_money"
|
25
52
|
remove "#{name}_currency"
|
26
53
|
end
|
54
|
+
remove_currency unless has_money_columns?
|
27
55
|
end
|
28
56
|
|
57
|
+
# Add a common currency column
|
58
|
+
#
|
59
|
+
# @return is not important and can change
|
60
|
+
#
|
61
|
+
# Add a common currency column and remove the individual
|
62
|
+
# currrency columns if they exist
|
63
|
+
def currency
|
64
|
+
remove_currency_columns
|
65
|
+
column :currency, :string
|
66
|
+
end
|
67
|
+
|
68
|
+
# Removes the common currency column
|
69
|
+
#
|
70
|
+
# Usually we create an currency column for each money
|
71
|
+
# columns. We can have multiple money columns in the same
|
72
|
+
# record, in which case we can have a single currency
|
73
|
+
# column. This helper removes that common curremcy column. For
|
74
|
+
# the existing money column it adds back their currency
|
75
|
+
# columns as well. It reflects on the database schema by
|
76
|
+
# looking at the column name. By convention the money amount
|
77
|
+
# column is prefixed by '_money' and the currency column by '_currency'
|
78
|
+
#
|
79
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#remove_currency
|
80
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::SchemaStatements#remove_money
|
81
|
+
# @see EasyRailsMoney::ActiveRecord::Migration::TableDefinition#currency
|
29
82
|
def remove_currency
|
30
83
|
remove :currency
|
31
84
|
money_columns do |money_column|
|
@@ -33,26 +86,38 @@ module EasyRailsMoney
|
|
33
86
|
end
|
34
87
|
end
|
35
88
|
|
89
|
+
protected
|
36
90
|
def remove_currency_columns
|
37
91
|
money_columns do |money_column|
|
38
92
|
remove "#{money_column}_currency"
|
39
93
|
end
|
40
94
|
end
|
41
|
-
|
42
|
-
protected
|
95
|
+
|
43
96
|
def columns
|
44
|
-
@base.schema_cache.
|
97
|
+
# @base.schema_cache.clear_table_cache! @table_name
|
98
|
+
@base.schema_cache.columns[@table_name].map { |x| x.name }
|
99
|
+
end
|
100
|
+
|
101
|
+
def has_currency_column?
|
102
|
+
columns.select { |x| x == "currency" }.any?
|
45
103
|
end
|
46
104
|
|
47
105
|
def money_columns
|
48
|
-
columns.select
|
49
|
-
col
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
106
|
+
columns.select { |col|
|
107
|
+
col =~ /_money/
|
108
|
+
}.map { |col|
|
109
|
+
name = col.match(/(.+)_money/)[1]
|
110
|
+
if block_given?
|
111
|
+
yield name
|
112
|
+
else
|
113
|
+
name
|
114
|
+
end
|
115
|
+
}
|
54
116
|
end
|
55
117
|
|
118
|
+
def has_money_columns?
|
119
|
+
money_columns.any?
|
120
|
+
end
|
56
121
|
end
|
57
122
|
end
|
58
123
|
end
|