easy_rails_money 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  *.gem
2
+ !vendor/cache/*
2
3
  *.rbc
3
4
  .bundle
4
5
  .config
data/.travis.yml ADDED
@@ -0,0 +1,20 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - "1.9.2"
5
+ - "1.9.3"
6
+ - jruby-19mode # JRuby in 1.9 mode
7
+ - rbx-19mode
8
+ - 2.0.0
9
+ # - jruby-18mode # JRuby in 1.8 mode
10
+ # - rbx-18mode
11
+ # - "1.8.7"
12
+
13
+ # uncomment this line if your project needs to run something other than `rake`:
14
+ # script: bundle exec rspec spec
15
+
16
+ matrix:
17
+ allow_failures:
18
+ - rvm: 2.0.0
19
+ - rvm: jruby-19mode
20
+ - rvm: rbx-19mode
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
- Under Development. only the migration part is done now
1
+ [![Build Status](https://travis-ci.org/deepak/easy_rails_money.png?branch=master)](https://travis-ci.org/deepak/easy_rails_money)
2
+ [![Dependency Status](https://gemnasium.com/deepak/easy_rails_money.png)](https://gemnasium.com/deepak/easy_rails_money)
3
+ [![Code Climate](https://codeclimate.com/github/deepak/easy_rails_money.png)](https://codeclimate.com/github/deepak/easy_rails_money)
4
+
5
+ ### Under Development. Only the migration part is done now
2
6
 
3
7
  # EasyRailsMoney
4
8
 
@@ -60,7 +64,7 @@ Watch [Rubyconf 2011 Float-is-legacy](http://www.confreaks.com/videos/698-rubyco
60
64
  We have encoded the currency in the column name. I like it because
61
65
  there is no need to define another column and it is simple. But the
62
66
  disadvantage is that it is inflexible and changing the column name in
63
- Mysql might require downtime for a big table
67
+ MySQL might require downtime for a big table
64
68
 
65
69
  So let us go with the first option. The disadvantage is that currency
66
70
  is stored as a string. Integer might be better for storing in the database
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
8
8
  gem.version = EasyRailsMoney::VERSION
9
9
  gem.authors = ["Deepak Kannan"]
10
10
  gem.email = ["kannan.deepak@gmail.com"]
11
- gem.description = %q{Integrate Rails's ActiveRecord gem and the money gem. Focus is on a simple code and API}
12
- gem.summary = %q{Integrate rails and the money gem}
11
+ gem.description = "Integrate Rail's ActiveRecord gem and the money gem. Focus is on a simple code and API"
12
+ gem.summary = "Integrate Rail's ActiveRecord gem and the money gem"
13
13
  gem.homepage = "https://github.com/deepak/easy_rails_money"
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
@@ -19,10 +19,10 @@ Gem::Specification.new do |gem|
19
19
 
20
20
  gem.add_dependency "money", "~> 5.1.1"
21
21
  gem.add_dependency "activesupport", "~> 3.2"
22
-
22
+
23
+ gem.add_development_dependency "rake", "~> 10.0.4"
23
24
  gem.add_development_dependency "rspec", "~> 2.12"
24
- gem.add_development_dependency "rails", "~> 3.2"
25
25
  gem.add_development_dependency "activerecord", "~> 3.2"
26
26
  gem.add_development_dependency "sqlite3", "~> 1.3.7"
27
- gem.add_development_dependency "debugger", "~> 1.3.3"
27
+ gem.add_development_dependency "debugger", "~> 1.5.0"
28
28
  end
@@ -4,14 +4,14 @@ module EasyRailsMoney
4
4
  module SchemaStatements
5
5
  def add_money(table_name, *columns)
6
6
  columns.each do |name|
7
- add_column table_name, name, :integer
7
+ add_column table_name, "#{name}_money", :integer
8
8
  add_column table_name, "#{name}_currency", :string
9
9
  end
10
10
  end
11
11
 
12
12
  def remove_money(table_name, *columns)
13
13
  columns.each do |name|
14
- remove_column table_name, name
14
+ remove_column table_name, "#{name}_money"
15
15
  remove_column table_name, "#{name}_currency"
16
16
  end
17
17
  end
@@ -2,19 +2,57 @@ module EasyRailsMoney
2
2
  module ActiveRecord
3
3
  module Migration
4
4
  module Table
5
- def money(*columns)
6
- columns.each do |name|
7
- column name, :integer
8
- column "#{name}_currency", :string
5
+ # called for change_table
6
+ # currency and #money defined in TableDefinition
7
+
8
+ def money(*column_names)
9
+ column_names.each do |name|
10
+ column "#{name}_money", :integer
11
+ unless columns.select { |x| x.name == "currency" }.any?
12
+ column "#{name}_currency", :string
13
+ end
14
+ end
15
+ end
16
+
17
+ def currency
18
+ remove_currency_columns
19
+ column :currency, :string
20
+ end
21
+
22
+ def remove_money(*column_names)
23
+ column_names.each do |name|
24
+ remove "#{name}_money"
25
+ remove "#{name}_currency"
9
26
  end
10
27
  end
11
28
 
12
- def remove_money(*columns)
13
- columns.each do |name|
14
- remove name, :integer
15
- remove "#{name}_currency", :string
29
+ def remove_currency
30
+ remove :currency
31
+ money_columns do |money_column|
32
+ column "#{money_column}_currency", "string"
16
33
  end
17
34
  end
35
+
36
+ def remove_currency_columns
37
+ money_columns do |money_column|
38
+ remove "#{money_column}_currency"
39
+ end
40
+ end
41
+
42
+ protected
43
+ def columns
44
+ @base.schema_cache.columns[@table_name]
45
+ end
46
+
47
+ def money_columns
48
+ columns.select do |col|
49
+ col.name =~ /_money/
50
+ end.map do |col|
51
+ money_column = col.name.match(/(.+)_money/)[1]
52
+ yield money_column
53
+ end
54
+ end
55
+
18
56
  end
19
57
  end
20
58
  end
@@ -0,0 +1,28 @@
1
+ module EasyRailsMoney
2
+ module ActiveRecord
3
+ module Migration
4
+ module TableDefinition
5
+ # called for create_table
6
+
7
+ def currency
8
+ remove_currency_columns
9
+ column :currency, :string
10
+ end
11
+
12
+ def money(*column_names)
13
+ column_names.each do |name|
14
+ column "#{name}_money", :integer
15
+ unless columns.select { |x| x.name == "currency" }.any?
16
+ column "#{name}_currency", :string
17
+ end
18
+ end
19
+ end
20
+
21
+ def remove_currency_columns
22
+ columns.delete_if { |x| x.name =~ /_currency/ }
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,8 +1,12 @@
1
1
  require "easy_rails_money/active_record/money_dsl"
2
2
  require "easy_rails_money/active_record/migration/schema_statements"
3
3
  require "easy_rails_money/active_record/migration/table"
4
+ require "easy_rails_money/active_record/migration/table_definition"
4
5
 
5
6
  ActiveRecord::Base.send :include, EasyRailsMoney::ActiveRecord::MoneyDsl
7
+
6
8
  ActiveRecord::Migration.send :include, EasyRailsMoney::ActiveRecord::Migration::SchemaStatements
7
- ActiveRecord::ConnectionAdapters::TableDefinition.send :include, EasyRailsMoney::ActiveRecord::Migration::Table
9
+
10
+ ActiveRecord::ConnectionAdapters::TableDefinition.send :include, EasyRailsMoney::ActiveRecord::Migration::TableDefinition
8
11
  ActiveRecord::ConnectionAdapters::Table.send :include, EasyRailsMoney::ActiveRecord::Migration::Table
12
+
@@ -1,3 +1,3 @@
1
1
  module EasyRailsMoney
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -2,16 +2,30 @@ require 'spec_helper'
2
2
  require 'active_record_spec_helper'
3
3
  require 'tempfile'
4
4
 
5
- class String
6
- def strip_spaces
7
- strip.gsub(/\s+/, ' ')
8
- end
9
- end
10
-
11
5
  if defined? ActiveRecord
12
6
 
13
7
  require 'active_record/schema_dumper'
14
8
 
9
+ class CreateLoan < ActiveRecord::Migration
10
+ def change
11
+ suppress_messages do
12
+ create_table :loans do |t|
13
+ t.string :name
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ class AddPrincipalToLoan < ActiveRecord::Migration
20
+ def change
21
+ suppress_messages do
22
+ change_table :loans do |t|
23
+ t.money :principal
24
+ end
25
+ end
26
+ end
27
+ end
28
+
15
29
  class CreateLoanWithPrincipal < ActiveRecord::Migration
16
30
  def change
17
31
  suppress_messages do
@@ -51,6 +65,81 @@ if defined? ActiveRecord
51
65
  end
52
66
  end
53
67
  end
68
+
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
77
+ end
78
+ end
79
+ end
80
+ end
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
91
+ end
92
+ end
93
+ end
94
+ end
95
+
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
105
+ end
106
+ end
107
+ end
108
+ end
109
+
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
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ class RemoveCurrencyFromLoan < ActiveRecord::Migration
125
+ def change
126
+ suppress_messages do
127
+ change_table :loans, force: true do |t|
128
+ t.remove_currency
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ class AddSingleCurrencyToLoan < ActiveRecord::Migration
135
+ def change
136
+ suppress_messages do
137
+ change_table :loans, force: true do |t|
138
+ t.currency
139
+ end
140
+ end
141
+ end
142
+ end
54
143
 
55
144
  # class Loan < ActiveRecord::Base
56
145
  # attr_accessible :principal, :name
@@ -63,7 +152,7 @@ if defined? ActiveRecord
63
152
  <<-EOF.strip_spaces
64
153
  create_table "loans", :force => true do |t|
65
154
  t.string "name"
66
- t.integer "principal"
155
+ t.integer "principal_money"
67
156
  t.string "principal_currency"
68
157
  end
69
158
  EOF
@@ -77,6 +166,32 @@ EOF
77
166
  EOF
78
167
  end
79
168
 
169
+ let(:schema_with_single_currency_column) do
170
+ <<-EOF.strip_spaces
171
+ create_table "loans", :force => true do |t|
172
+ t.string "name"
173
+ t.integer "npa_money"
174
+ t.integer "principal_money"
175
+ t.integer "repaid_money"
176
+ t.string "currency"
177
+ end
178
+ EOF
179
+ end
180
+
181
+ let(:schema_with_multiple_currency_columns) do
182
+ <<-EOF.strip_spaces
183
+ create_table "loans", :force => true do |t|
184
+ t.string "name"
185
+ t.string "npa_currency"
186
+ t.integer "npa_money"
187
+ t.string "principal_currency"
188
+ t.integer "principal_money"
189
+ t.string "repaid_currency"
190
+ t.integer "repaid_money"
191
+ end
192
+ EOF
193
+ end
194
+
80
195
  context "schema_statements" do
81
196
  before(:each) do
82
197
  migrate CreateLoanWithPrincipal
@@ -112,9 +227,40 @@ EOF
112
227
  end
113
228
  end
114
229
  end
115
-
116
-
117
- end
118
- end
119
230
 
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
236
+
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
241
+ end
242
+
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
246
+ end
247
+ end
248
+
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
253
+
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)
257
+ end
258
+ end
259
+
260
+ 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)
263
+ end
120
264
 
265
+ end # describe "migration"
266
+ end # if defined? ActiveRecord
@@ -1,9 +1,61 @@
1
+ class String
2
+ def strip_spaces
3
+ strip.gsub(/\s+/, ' ')
4
+ end
5
+ end
6
+
7
+ module DumpSchemaHelpers
8
+ # we have a single canonical representation for testing
9
+ # different migrations insert the currency column in different
10
+ # places. but for representation we would like it at the end
11
+ # also the money and currency columns are represented as following
12
+ # each other. eg.
13
+ # t.string "principal_currency"
14
+ # t.string "principal_currency"
15
+ def canonical_representation schema
16
+ schema = schema.strip.split("\n")
17
+ return "" if schema.blank?
18
+
19
+ schema = move_currency_column_last schema
20
+ schema = interleave_money_and_currency_columns schema
21
+
22
+ schema.join('').strip_spaces
23
+ end
24
+ module_function :canonical_representation
25
+
26
+ def interleave_money_and_currency_columns schema
27
+ money_columns = schema.select {|x| x =~ /_money/ }
28
+ currency_columns = schema.select {|x| x =~ /_currency/ }
29
+
30
+ schema.delete_if {|x| x =~ /_money/ }
31
+ schema.delete_if {|x| x =~ /_currency/ }
32
+
33
+ schema[0..1] +
34
+ (money_columns + currency_columns).sort_by { |x| x.match(/t\.(.+)\"(?<logical_column>.+)_(money|currency).+/)[:logical_column] } +
35
+ schema[2..-1]
36
+ end
37
+ module_function :interleave_money_and_currency_columns
38
+
39
+ def move_currency_column_last schema
40
+ currency_column = " t.string \"currency\""
41
+
42
+ unless schema.select {|x| x == currency_column }.empty?
43
+ schema.delete_if {|x| x == currency_column }
44
+ last = schema.pop
45
+ schema.push currency_column
46
+ schema.push last
47
+ end
48
+ schema
49
+ end
50
+ module_function :move_currency_column_last
51
+ end
52
+
1
53
  module SchemaHelpers
2
54
  def dump_schema
3
55
  Tempfile.open('schema', encoding: "utf-8") do |schema_file|
4
56
  ActiveRecord::SchemaDumper.send(:new, ActiveRecord::Base.connection).send(:tables, schema_file)
5
57
  schema_file.rewind
6
- schema_file.read.strip_spaces
58
+ DumpSchemaHelpers.canonical_representation schema_file.read
7
59
  end
8
60
  end
9
61
 
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'active_record'
2
2
  require_relative '../lib/easy_rails_money'
3
3
 
4
-
4
+ RSpec.configure do |c|
5
+ c.treat_symbols_as_metadata_keys_with_true_values = true
6
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy_rails_money
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-28 00:00:00.000000000 Z
12
+ date: 2013-03-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: money
@@ -44,13 +44,13 @@ dependencies:
44
44
  - !ruby/object:Gem::Version
45
45
  version: '3.2'
46
46
  - !ruby/object:Gem::Dependency
47
- name: rspec
47
+ name: rake
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
51
  - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: '2.12'
53
+ version: 10.0.4
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,15 +58,15 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: '2.12'
61
+ version: 10.0.4
62
62
  - !ruby/object:Gem::Dependency
63
- name: rails
63
+ name: rspec
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
67
67
  - - ~>
68
68
  - !ruby/object:Gem::Version
69
- version: '3.2'
69
+ version: '2.12'
70
70
  type: :development
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -74,7 +74,7 @@ dependencies:
74
74
  requirements:
75
75
  - - ~>
76
76
  - !ruby/object:Gem::Version
77
- version: '3.2'
77
+ version: '2.12'
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: activerecord
80
80
  requirement: !ruby/object:Gem::Requirement
@@ -114,7 +114,7 @@ dependencies:
114
114
  requirements:
115
115
  - - ~>
116
116
  - !ruby/object:Gem::Version
117
- version: 1.3.3
117
+ version: 1.5.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
@@ -122,8 +122,8 @@ dependencies:
122
122
  requirements:
123
123
  - - ~>
124
124
  - !ruby/object:Gem::Version
125
- version: 1.3.3
126
- description: Integrate Rails's ActiveRecord gem and the money gem. Focus is on a simple
125
+ version: 1.5.0
126
+ description: Integrate Rail's ActiveRecord gem and the money gem. Focus is on a simple
127
127
  code and API
128
128
  email:
129
129
  - kannan.deepak@gmail.com
@@ -132,6 +132,7 @@ extensions: []
132
132
  extra_rdoc_files: []
133
133
  files:
134
134
  - .gitignore
135
+ - .travis.yml
135
136
  - Gemfile
136
137
  - LICENSE.txt
137
138
  - README.md
@@ -141,6 +142,7 @@ files:
141
142
  - lib/easy_rails_money/active_record.rb
142
143
  - lib/easy_rails_money/active_record/migration/schema_statements.rb
143
144
  - lib/easy_rails_money/active_record/migration/table.rb
145
+ - lib/easy_rails_money/active_record/migration/table_definition.rb
144
146
  - lib/easy_rails_money/active_record/money_dsl.rb
145
147
  - lib/easy_rails_money/configuration.rb
146
148
  - lib/easy_rails_money/version.rb
@@ -149,6 +151,26 @@ files:
149
151
  - spec/active_record_spec_helper.rb
150
152
  - spec/configuration_spec.rb
151
153
  - spec/spec_helper.rb
154
+ - vendor/cache/activemodel-3.2.12.gem
155
+ - vendor/cache/activerecord-3.2.12.gem
156
+ - vendor/cache/activesupport-3.2.12.gem
157
+ - vendor/cache/arel-3.0.2.gem
158
+ - vendor/cache/builder-3.0.4.gem
159
+ - vendor/cache/columnize-0.3.6.gem
160
+ - vendor/cache/debugger-1.5.0.gem
161
+ - vendor/cache/debugger-linecache-1.2.0.gem
162
+ - vendor/cache/debugger-ruby_core_source-1.2.0.gem
163
+ - vendor/cache/diff-lcs-1.2.1.gem
164
+ - vendor/cache/i18n-0.6.4.gem
165
+ - vendor/cache/money-5.1.1.gem
166
+ - vendor/cache/multi_json-1.7.2.gem
167
+ - vendor/cache/rake-10.0.4.gem
168
+ - vendor/cache/rspec-2.13.0.gem
169
+ - vendor/cache/rspec-core-2.13.1.gem
170
+ - vendor/cache/rspec-expectations-2.13.0.gem
171
+ - vendor/cache/rspec-mocks-2.13.0.gem
172
+ - vendor/cache/sqlite3-1.3.7.gem
173
+ - vendor/cache/tzinfo-0.3.37.gem
152
174
  homepage: https://github.com/deepak/easy_rails_money
153
175
  licenses: []
154
176
  post_install_message:
@@ -172,7 +194,7 @@ rubyforge_project:
172
194
  rubygems_version: 1.8.24
173
195
  signing_key:
174
196
  specification_version: 3
175
- summary: Integrate rails and the money gem
197
+ summary: Integrate Rail's ActiveRecord gem and the money gem
176
198
  test_files:
177
199
  - spec/active_record/migration_spec.rb
178
200
  - spec/active_record/money_dsl_spec.rb