easy_rails_money 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Dependency Status](https://gemnasium.com/deepak/easy_rails_money.png)](https://gemnasium.com/deepak/easy_rails_money)
|
3
3
|
[![Code Climate](https://codeclimate.com/github/deepak/easy_rails_money.png)](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
|