money-rails 0.1.0 → 0.2.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0
4
+
5
+ - Add new generator to install money.rb initializer
6
+ - Create a structure to enable better ORM/ODM integration
7
+ - Add configuration for numericality validation of monetized fields
8
+ - Add support for custom currency registration
9
+
10
+ ## 0.1.0
11
+
12
+ - Use better names for args :target_name, :field_currency,
13
+ :model_currency. From now on, :as, :with_currency and :with_model_currency should
14
+ be used instead of the old ones which are deprecated. (GH-6)
15
+
16
+ ## 0.0.1
17
+
18
+ - Hello World
19
+
data/README.md CHANGED
@@ -24,6 +24,14 @@ Or install it yourself as:
24
24
 
25
25
  $ gem install money-rails
26
26
 
27
+ You may also install money configuration initializer:
28
+
29
+ ```
30
+ $ rails g money_rails:initializer
31
+ ```
32
+
33
+ There, you can define the default currency value and set other
34
+ configuration parameters for the rails app.
27
35
 
28
36
  ## Usage
29
37
 
@@ -49,11 +57,11 @@ money attribute, then you can provide ```as``` argument with a string
49
57
  value to the ```monetize``` macro:
50
58
 
51
59
  ```ruby
52
- monetize :discount, :as => "discount_value"
60
+ monetize :discount_subunit, :as => "discount"
53
61
  ```
54
62
 
55
- Now the model objects will have a ```discount_value``` attribute which
56
- is a Money object, wrapping the value of ```discount``` column to a
63
+ Now the model objects will have a ```discount``` attribute which
64
+ is a Money object, wrapping the value of ```discount_subunit``` column to a
57
65
  Money instance.
58
66
 
59
67
  ### Field currencies
@@ -61,12 +69,58 @@ Money instance.
61
69
  You can define a specific currency per monetized field:
62
70
 
63
71
  ```ruby
64
- monetize :discount, :as => "discount_value", :with_currency => :eur
72
+ monetize :discount_subunit, :as => "discount", :with_currency => :eur
65
73
  ```
66
74
 
67
- Now ```discount_value``` will give you a Money object using EUR as
75
+ Now ```discount_subunit``` will give you a Money object using EUR as
68
76
  currency.
69
77
 
78
+ ### Configuration parameters
79
+
80
+ You can handle a bunch of configuration params through ```money.rb``` initializer:
81
+
82
+ ```
83
+ MoneyRails.configure do |config|
84
+
85
+ # To set the default currency
86
+ #
87
+ config.default_currency = :usd
88
+
89
+ # To handle the inclusion of validations for monetized fields
90
+ # The default value is true
91
+ #
92
+ config.include_validations = true
93
+
94
+ # Register a custom currency
95
+ #
96
+ # config.register_currency = {
97
+ # :priority => 1,
98
+ # :iso_code => "EU4",
99
+ # :name => "Euro with subunit of 4 digits",
100
+ # :symbol => "€",
101
+ # :symbol_first => true,
102
+ # :subunit => "Subcent",
103
+ # :subunit_to_unit => 10000,
104
+ # :thousands_separator => ".",
105
+ # :decimal_mark => ","
106
+ # }
107
+ end
108
+ ```
109
+
110
+ * default_currecy: Set the default (application wide) currency (USD is the default)
111
+ * include_validations: Permit the inclusion of a ```validates_numericality_of```
112
+ validation for each monetized field (the default is true)
113
+ * register_currency: Register one custom currency. This option can be
114
+ used more than once to set more custom currencies. The value should be
115
+ a hash of all the necessary key/value pairs (important keys: :priority, :iso_code, :name,
116
+ :symbol, :symbol_first, :subunit, :subunit_to_unit, :thousands_separator, :decimal_mark).
117
+
118
+ ## Maintainers
119
+
120
+ * Andreas Loupasakis (https://github.com/alup)
121
+ * Shane Emmons (https://github.com/semmons99)
122
+ * Simone Carletti (https://github.com/weppos)
123
+
70
124
  ## License
71
125
 
72
126
  MIT License. Copyright 2012 RubyMoney.
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+
6
+ begin
7
+ Bundler.setup(:default, :development)
8
+ rescue Bundler::BundlerError => e
9
+ $stderr.puts e.message
10
+ $stderr.puts "Run `bundle install` to install missing gems"
11
+ exit e.status_code
12
+ end
13
+
14
+ require 'rake'
15
+ require 'rspec/core/rake_task'
16
+
17
+ RSpec::Core::RakeTask.new
18
+
19
+ task :default => :spec
20
+ task :test => :spec
@@ -0,0 +1,15 @@
1
+ module MoneyRails
2
+ module Generators
3
+ class InitializerGenerator < ::Rails::Generators::Base
4
+
5
+ source_root File.expand_path("../../templates", __FILE__)
6
+
7
+ desc 'Creates a sample MoneyRails initializer.'
8
+
9
+ def copy_initializer
10
+ copy_file 'money.rb', 'config/initializers/money.rb'
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ # encoding : utf-8
2
+
3
+ MoneyRails.configure do |config|
4
+
5
+ # To set the default currency
6
+ #
7
+ #config.default_currency = :usd
8
+
9
+ # To handle the inclusion of validations for monetized fields
10
+ # The default value is true
11
+ #
12
+ #config.include_validations = true
13
+
14
+ # Register a custom currency
15
+ #
16
+ # Example:
17
+ # config.register_currency = {
18
+ # :priority => 1,
19
+ # :iso_code => "EU4",
20
+ # :name => "Euro with subunit of 4 digits",
21
+ # :symbol => "€",
22
+ # :symbol_first => true,
23
+ # :subunit => "Subcent",
24
+ # :subunit_to_unit => 10000,
25
+ # :thousands_separator => ".",
26
+ # :decimal_mark => ","
27
+ # }
28
+
29
+ end
data/lib/money-rails.rb CHANGED
@@ -1,5 +1,11 @@
1
1
  require "money"
2
+ require "money-rails/configuration"
3
+
4
+ module MoneyRails
5
+ extend Configuration
6
+
7
+ end
2
8
 
3
9
  require "money-rails/version"
4
- require "money-rails/monetize"
10
+ require "money-rails/orms"
5
11
  require "money-rails/railtie"
@@ -0,0 +1,78 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/core_ext/array/extract_options'
3
+ require 'active_support/deprecation/reporting'
4
+
5
+ module MoneyRails
6
+ module ActiveRecord
7
+ module Monetizable
8
+ extend ActiveSupport::Concern
9
+
10
+ module ClassMethods
11
+ def monetize(field, *args)
12
+ options = args.extract_options!
13
+
14
+ # Stringify model field name
15
+ subunit_name = field.to_s
16
+
17
+ if options[:field_currency] || options[:target_name] ||
18
+ options[:model_currency]
19
+ ActiveSupport::Deprecation.warn("You are using the old " \
20
+ "argument keys of monetize command! Instead use :as, " \
21
+ ":with_currency or :with_model_currency")
22
+ end
23
+
24
+ # Model currency field name
25
+ model_currency_name = options[:with_model_currency] ||
26
+ options[:model_currency] || "currency"
27
+
28
+ # Override Model and default currency
29
+ field_currency_name = options[:with_currency] ||
30
+ options[:field_currency] || nil
31
+
32
+ name = options[:as] || options[:target_name] || nil
33
+
34
+ # Form target name for the money backed ActiveModel field:
35
+ # if a target name is provided then use it
36
+ # if there is a "_cents" suffix then just remove it to create the target name
37
+ # if none of the previous is the case then use a default suffix
38
+ if name
39
+ name = name.to_s
40
+ elsif subunit_name =~ /_cents$/
41
+ name = subunit_name.sub(/_cents$/, "")
42
+ else
43
+ # FIXME: provide a better default
44
+ name = subunit_name << "_money"
45
+ end
46
+
47
+ class_eval do
48
+ composed_of name.to_sym,
49
+ :class_name => "Money",
50
+ :mapping => [[subunit_name, "cents"], [model_currency_name, "currency_as_string"]],
51
+ :constructor => Proc.new { |cents, currency|
52
+ Money.new(cents || 0, field_currency_name || currency ||
53
+ Money.default_currency)
54
+ },
55
+ :converter => Proc.new { |value|
56
+ if value.respond_to?(:to_money)
57
+ if field_currency_name
58
+ value.to_money(field_currency_name)
59
+ else
60
+ value.to_money
61
+ end
62
+ else
63
+ raise(ArgumentError, "Can't convert #{value.class} to Money")
64
+ end
65
+ }
66
+ end
67
+
68
+ # Include numericality validation if needed
69
+ if MoneyRails.include_validations
70
+ class_eval do
71
+ validates_numericality_of subunit_name
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,33 @@
1
+ module MoneyRails
2
+
3
+ # MoneyRails configuration module.
4
+ # This is extended by MoneyRails to provide configuration settings.
5
+ module Configuration
6
+
7
+ # Start a MoneyRails configuration block in an initializer.
8
+ #
9
+ # example: Provide a default currency for the application
10
+ # MoneyRails.configure do |config|
11
+ # config.default_currency = :eur
12
+ # end
13
+ def configure
14
+ yield self
15
+ end
16
+
17
+ # Configuration parameters
18
+
19
+ # Set default currency of money library
20
+ def default_currency=(currency_name)
21
+ Money.default_currency = Money::Currency.new(currency_name)
22
+ end
23
+
24
+ # Register a custom currency
25
+ def register_currency=(currency_options)
26
+ Money::Currency.register(currency_options)
27
+ end
28
+
29
+ # Use (by default) validation of numericality for each monetized field.
30
+ mattr_accessor :include_validations
31
+ @@include_validations = true
32
+ end
33
+ end
@@ -0,0 +1,29 @@
1
+ require "active_support/lazy_load_hooks"
2
+
3
+ # Thnx to Kristian Mandrup for the inspiration
4
+ # TODO: Include more ORMs/ODMs here
5
+
6
+ module MoneyRails
7
+ module Orms
8
+ def self.extend_for(name=:active_record)
9
+ case name.to_sym
10
+ when :active_record
11
+ if defined?(ActiveRecord::Base)
12
+ require "money-rails/active_record/monetizable"
13
+
14
+ # Lazy load extension
15
+ ActiveSupport.on_load :active_record do
16
+ include MoneyRails::ActiveRecord::Monetizable
17
+ end
18
+ end
19
+ else
20
+ raise ArgumentError, "ORM extension for #{name} is currently not supported."
21
+ end
22
+ end
23
+
24
+ # Return all supported ORMs
25
+ def self.supported
26
+ %w{active_record}
27
+ end
28
+ end
29
+ end
@@ -2,9 +2,7 @@ module MoneyRails
2
2
  module Monetizable
3
3
  class Railtie < ::Rails::Railtie
4
4
  initializer "moneyrails.initialize" do
5
- ActiveSupport.on_load(:active_record) do
6
- include MoneyRails::Monetizable
7
- end
5
+ MoneyRails::Orms.extend_for :active_record
8
6
  end
9
7
  end
10
8
  end
@@ -1,3 +1,3 @@
1
1
  module MoneyRails
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/money-rails.gemspec CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
13
13
  s.homepage = "https://github.com/RubyMoney/money"
14
14
 
15
15
  s.files = Dir.glob("{lib,spec}/**/*")
16
- s.files += %w(LICENSE README.md)
17
- s.files += %w(money-rails.gemspec)
16
+ s.files += %w(CHANGELOG.md LICENSE README.md)
17
+ s.files += %w(Rakefile money-rails.gemspec)
18
18
 
19
19
  s.test_files = s.files.grep(/^spec\//)
20
20
 
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe "configuration" do
4
+
5
+ describe "initializer" do
6
+
7
+ it "sets default currency" do
8
+ Money.default_currency.should == Money::Currency.new(:eur)
9
+ end
10
+
11
+ it "registers a custom currency" do
12
+ Money::Currency.table.should include(:eu4)
13
+ end
14
+ end
15
+ end
@@ -1 +1,27 @@
1
- Money.default_currency = Money::Currency.new("USD")
1
+ # encoding : utf-8
2
+
3
+ MoneyRails.configure do |config|
4
+
5
+ # To set the default currency
6
+ #
7
+ config.default_currency = :eur
8
+
9
+ # To handle the inclusion of validations for monetized fields
10
+ # The default value is true
11
+ #
12
+ config.include_validations = true
13
+
14
+ # Register a custom currency
15
+ #
16
+ config.register_currency = {
17
+ :priority => 1,
18
+ :iso_code => "EU4",
19
+ :name => "Euro with subunit of 4 digits",
20
+ :symbol => "€",
21
+ :symbol_first => true,
22
+ :subunit => "Subcent",
23
+ :subunit_to_unit => 10000,
24
+ :thousands_separator => ".",
25
+ :decimal_mark => ","
26
+ }
27
+ end
@@ -167,3 +167,380 @@
167
167
  SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Sat, 21 Apr 2012 10:56:06 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Sat, 21 Apr 2012 10:56:06 UTC +00:00]]
168
168
   (0.1ms) RELEASE SAVEPOINT active_record_1
169
169
   (0.2ms) rollback transaction
170
+  (0.4ms) begin transaction
171
+  (0.1ms) rollback transaction
172
+  (0.1ms) begin transaction
173
+  (0.1ms) SAVEPOINT active_record_1
174
+ SQL (25.5ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Sat, 28 Apr 2012 15:26:59 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Sat, 28 Apr 2012 15:26:59 UTC +00:00]]
175
+  (0.1ms) RELEASE SAVEPOINT active_record_1
176
+  (0.1ms) rollback transaction
177
+  (0.0ms) begin transaction
178
+  (0.0ms) SAVEPOINT active_record_1
179
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Sat, 28 Apr 2012 15:26:59 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Sat, 28 Apr 2012 15:26:59 UTC +00:00]]
180
+  (0.0ms) RELEASE SAVEPOINT active_record_1
181
+  (0.1ms) rollback transaction
182
+  (0.0ms) begin transaction
183
+  (0.0ms) SAVEPOINT active_record_1
184
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Sat, 28 Apr 2012 15:26:59 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Sat, 28 Apr 2012 15:26:59 UTC +00:00]]
185
+  (0.0ms) RELEASE SAVEPOINT active_record_1
186
+  (0.1ms) rollback transaction
187
+  (0.4ms) begin transaction
188
+  (0.0ms) rollback transaction
189
+  (0.1ms) begin transaction
190
+  (0.1ms) SAVEPOINT active_record_1
191
+ SQL (4.2ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Sat, 28 Apr 2012 17:52:22 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Sat, 28 Apr 2012 17:52:22 UTC +00:00]]
192
+  (0.1ms) RELEASE SAVEPOINT active_record_1
193
+  (0.1ms) rollback transaction
194
+  (0.0ms) begin transaction
195
+  (0.0ms) SAVEPOINT active_record_1
196
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Sat, 28 Apr 2012 17:52:22 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Sat, 28 Apr 2012 17:52:22 UTC +00:00]]
197
+  (0.0ms) RELEASE SAVEPOINT active_record_1
198
+  (0.1ms) rollback transaction
199
+  (0.1ms) begin transaction
200
+  (0.0ms) SAVEPOINT active_record_1
201
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Sat, 28 Apr 2012 17:52:22 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Sat, 28 Apr 2012 17:52:22 UTC +00:00]]
202
+  (0.0ms) RELEASE SAVEPOINT active_record_1
203
+  (0.1ms) rollback transaction
204
+  (0.4ms) begin transaction
205
+  (0.0ms) rollback transaction
206
+  (0.0ms) begin transaction
207
+  (0.1ms) SAVEPOINT active_record_1
208
+ SQL (4.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Sat, 28 Apr 2012 18:04:22 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Sat, 28 Apr 2012 18:04:22 UTC +00:00]]
209
+  (0.1ms) RELEASE SAVEPOINT active_record_1
210
+  (0.1ms) rollback transaction
211
+  (0.1ms) begin transaction
212
+  (0.0ms) SAVEPOINT active_record_1
213
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Sat, 28 Apr 2012 18:04:22 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Sat, 28 Apr 2012 18:04:22 UTC +00:00]]
214
+  (0.0ms) RELEASE SAVEPOINT active_record_1
215
+  (0.1ms) rollback transaction
216
+  (0.0ms) begin transaction
217
+  (0.0ms) SAVEPOINT active_record_1
218
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Sat, 28 Apr 2012 18:04:22 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Sat, 28 Apr 2012 18:04:22 UTC +00:00]]
219
+  (0.0ms) RELEASE SAVEPOINT active_record_1
220
+  (0.1ms) rollback transaction
221
+  (0.6ms) begin transaction
222
+  (0.1ms) rollback transaction
223
+  (0.1ms) begin transaction
224
+  (0.1ms) SAVEPOINT active_record_1
225
+ SQL (23.1ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:14:47 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:14:47 UTC +00:00]]
226
+  (0.1ms) RELEASE SAVEPOINT active_record_1
227
+  (0.1ms) rollback transaction
228
+  (0.0ms) begin transaction
229
+  (0.0ms) SAVEPOINT active_record_1
230
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:14:47 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:14:47 UTC +00:00]]
231
+  (0.0ms) RELEASE SAVEPOINT active_record_1
232
+  (0.1ms) rollback transaction
233
+  (0.0ms) begin transaction
234
+  (0.0ms) SAVEPOINT active_record_1
235
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:14:47 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:14:47 UTC +00:00]]
236
+  (0.0ms) RELEASE SAVEPOINT active_record_1
237
+  (0.1ms) rollback transaction
238
+  (0.0ms) begin transaction
239
+  (0.0ms) SAVEPOINT active_record_1
240
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:14:47 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:14:47 UTC +00:00]]
241
+  (0.0ms) RELEASE SAVEPOINT active_record_1
242
+  (0.0ms) SAVEPOINT active_record_1
243
+  (0.1ms) ROLLBACK TO SAVEPOINT active_record_1
244
+  (0.2ms) rollback transaction
245
+  (0.6ms) begin transaction
246
+  (0.0ms) rollback transaction
247
+  (0.1ms) begin transaction
248
+  (0.1ms) SAVEPOINT active_record_1
249
+ SQL (5.5ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:15:34 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:15:34 UTC +00:00]]
250
+  (0.1ms) RELEASE SAVEPOINT active_record_1
251
+  (0.1ms) rollback transaction
252
+  (0.0ms) begin transaction
253
+  (0.0ms) SAVEPOINT active_record_1
254
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:15:34 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:15:34 UTC +00:00]]
255
+  (0.0ms) RELEASE SAVEPOINT active_record_1
256
+  (0.1ms) rollback transaction
257
+  (0.0ms) begin transaction
258
+  (0.0ms) SAVEPOINT active_record_1
259
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:15:34 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:15:34 UTC +00:00]]
260
+  (0.0ms) RELEASE SAVEPOINT active_record_1
261
+  (0.1ms) rollback transaction
262
+  (0.0ms) begin transaction
263
+  (0.0ms) SAVEPOINT active_record_1
264
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:15:34 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:15:34 UTC +00:00]]
265
+  (0.0ms) RELEASE SAVEPOINT active_record_1
266
+  (0.0ms) SAVEPOINT active_record_1
267
+  (0.1ms) ROLLBACK TO SAVEPOINT active_record_1
268
+  (0.1ms) SAVEPOINT active_record_1
269
+  (0.3ms) UPDATE "products" SET "price_cents" = 2000, "updated_at" = '2012-04-30 23:15:34.779479' WHERE "products"."id" = 1
270
+  (0.0ms) RELEASE SAVEPOINT active_record_1
271
+  (0.2ms) rollback transaction
272
+  (0.4ms) begin transaction
273
+  (0.0ms) rollback transaction
274
+  (0.0ms) begin transaction
275
+  (0.1ms) SAVEPOINT active_record_1
276
+ SQL (4.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:23:36 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:23:36 UTC +00:00]]
277
+  (0.1ms) RELEASE SAVEPOINT active_record_1
278
+  (0.2ms) rollback transaction
279
+  (0.0ms) begin transaction
280
+  (0.0ms) SAVEPOINT active_record_1
281
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:23:36 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:23:36 UTC +00:00]]
282
+  (0.0ms) RELEASE SAVEPOINT active_record_1
283
+  (0.1ms) rollback transaction
284
+  (0.1ms) begin transaction
285
+  (0.0ms) SAVEPOINT active_record_1
286
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:23:36 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:23:36 UTC +00:00]]
287
+  (0.0ms) RELEASE SAVEPOINT active_record_1
288
+  (0.1ms) rollback transaction
289
+  (0.0ms) begin transaction
290
+  (0.0ms) SAVEPOINT active_record_1
291
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:23:36 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:23:36 UTC +00:00]]
292
+  (0.0ms) RELEASE SAVEPOINT active_record_1
293
+  (0.1ms) rollback transaction
294
+  (0.0ms) begin transaction
295
+  (0.0ms) SAVEPOINT active_record_1
296
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:23:36 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:23:36 UTC +00:00]]
297
+  (0.0ms) RELEASE SAVEPOINT active_record_1
298
+  (0.0ms) SAVEPOINT active_record_1
299
+  (0.1ms) ROLLBACK TO SAVEPOINT active_record_1
300
+  (0.1ms) SAVEPOINT active_record_1
301
+  (0.3ms) UPDATE "products" SET "price_cents" = 2000, "updated_at" = '2012-04-30 23:23:36.931350' WHERE "products"."id" = 1
302
+  (0.0ms) RELEASE SAVEPOINT active_record_1
303
+  (0.1ms) rollback transaction
304
+  (0.4ms) begin transaction
305
+  (0.0ms) rollback transaction
306
+  (0.0ms) begin transaction
307
+  (0.1ms) SAVEPOINT active_record_1
308
+ SQL (4.2ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00]]
309
+  (0.1ms) RELEASE SAVEPOINT active_record_1
310
+  (0.1ms) rollback transaction
311
+  (0.1ms) begin transaction
312
+  (0.0ms) SAVEPOINT active_record_1
313
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00]]
314
+  (0.0ms) RELEASE SAVEPOINT active_record_1
315
+  (0.1ms) rollback transaction
316
+  (0.0ms) begin transaction
317
+  (0.0ms) SAVEPOINT active_record_1
318
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00]]
319
+  (0.0ms) RELEASE SAVEPOINT active_record_1
320
+  (0.2ms) rollback transaction
321
+  (0.1ms) begin transaction
322
+  (0.1ms) SAVEPOINT active_record_1
323
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00]]
324
+  (0.1ms) RELEASE SAVEPOINT active_record_1
325
+  (0.1ms) rollback transaction
326
+  (0.1ms) begin transaction
327
+  (0.0ms) SAVEPOINT active_record_1
328
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00]]
329
+  (0.0ms) RELEASE SAVEPOINT active_record_1
330
+  (0.1ms) rollback transaction
331
+  (0.1ms) begin transaction
332
+  (0.0ms) SAVEPOINT active_record_1
333
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:20 UTC +00:00]]
334
+  (0.0ms) RELEASE SAVEPOINT active_record_1
335
+  (0.0ms) SAVEPOINT active_record_1
336
+  (0.0ms) ROLLBACK TO SAVEPOINT active_record_1
337
+  (0.1ms) SAVEPOINT active_record_1
338
+  (0.3ms) UPDATE "products" SET "price_cents" = 2000, "updated_at" = '2012-04-30 23:29:20.101664' WHERE "products"."id" = 1
339
+  (0.1ms) RELEASE SAVEPOINT active_record_1
340
+  (0.1ms) rollback transaction
341
+  (0.5ms) begin transaction
342
+  (0.0ms) rollback transaction
343
+  (0.1ms) begin transaction
344
+  (0.1ms) SAVEPOINT active_record_1
345
+ SQL (4.7ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00]]
346
+  (0.1ms) RELEASE SAVEPOINT active_record_1
347
+  (0.2ms) rollback transaction
348
+  (0.1ms) begin transaction
349
+  (0.0ms) SAVEPOINT active_record_1
350
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00]]
351
+  (0.1ms) RELEASE SAVEPOINT active_record_1
352
+  (0.1ms) rollback transaction
353
+  (0.0ms) begin transaction
354
+  (0.0ms) SAVEPOINT active_record_1
355
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00]]
356
+  (0.0ms) RELEASE SAVEPOINT active_record_1
357
+  (0.0ms) SAVEPOINT active_record_1
358
+  (0.3ms) UPDATE "products" SET "price_cents" = 3210, "currency" = 'EUR', "updated_at" = '2012-04-30 23:29:35.897484' WHERE "products"."id" = 1
359
+  (0.1ms) RELEASE SAVEPOINT active_record_1
360
+  (0.3ms) rollback transaction
361
+  (0.1ms) begin transaction
362
+  (0.0ms) SAVEPOINT active_record_1
363
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00]]
364
+  (0.1ms) RELEASE SAVEPOINT active_record_1
365
+  (0.1ms) rollback transaction
366
+  (0.1ms) begin transaction
367
+  (0.0ms) SAVEPOINT active_record_1
368
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00]]
369
+  (0.1ms) RELEASE SAVEPOINT active_record_1
370
+  (0.1ms) rollback transaction
371
+  (0.1ms) begin transaction
372
+  (0.0ms) SAVEPOINT active_record_1
373
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:29:35 UTC +00:00]]
374
+  (0.1ms) RELEASE SAVEPOINT active_record_1
375
+  (0.0ms) SAVEPOINT active_record_1
376
+  (0.1ms) ROLLBACK TO SAVEPOINT active_record_1
377
+  (0.0ms) SAVEPOINT active_record_1
378
+  (0.2ms) UPDATE "products" SET "price_cents" = 2000, "updated_at" = '2012-04-30 23:29:35.943571' WHERE "products"."id" = 1
379
+  (0.0ms) RELEASE SAVEPOINT active_record_1
380
+  (0.2ms) rollback transaction
381
+  (0.4ms) begin transaction
382
+  (0.0ms) rollback transaction
383
+  (0.0ms) begin transaction
384
+  (0.1ms) SAVEPOINT active_record_1
385
+ SQL (4.6ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00]]
386
+  (0.1ms) RELEASE SAVEPOINT active_record_1
387
+  (0.1ms) rollback transaction
388
+  (0.1ms) begin transaction
389
+  (0.0ms) SAVEPOINT active_record_1
390
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00]]
391
+  (0.0ms) RELEASE SAVEPOINT active_record_1
392
+  (0.1ms) rollback transaction
393
+  (0.0ms) begin transaction
394
+  (0.0ms) SAVEPOINT active_record_1
395
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00]]
396
+  (0.0ms) RELEASE SAVEPOINT active_record_1
397
+  (0.0ms) SAVEPOINT active_record_1
398
+  (0.2ms) UPDATE "products" SET "price_cents" = 3210, "currency" = 'EUR', "updated_at" = '2012-04-30 23:38:21.163930' WHERE "products"."id" = 1
399
+  (0.0ms) RELEASE SAVEPOINT active_record_1
400
+  (0.2ms) rollback transaction
401
+  (0.1ms) begin transaction
402
+  (0.0ms) SAVEPOINT active_record_1
403
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00]]
404
+  (0.0ms) RELEASE SAVEPOINT active_record_1
405
+  (0.1ms) rollback transaction
406
+  (0.1ms) begin transaction
407
+  (0.0ms) SAVEPOINT active_record_1
408
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00]]
409
+  (0.1ms) RELEASE SAVEPOINT active_record_1
410
+  (0.1ms) rollback transaction
411
+  (0.1ms) begin transaction
412
+  (0.0ms) SAVEPOINT active_record_1
413
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Mon, 30 Apr 2012 23:38:21 UTC +00:00]]
414
+  (0.0ms) RELEASE SAVEPOINT active_record_1
415
+  (0.0ms) SAVEPOINT active_record_1
416
+  (0.1ms) ROLLBACK TO SAVEPOINT active_record_1
417
+  (0.1ms) SAVEPOINT active_record_1
418
+  (0.2ms) UPDATE "products" SET "price_cents" = 2000, "updated_at" = '2012-04-30 23:38:21.209437' WHERE "products"."id" = 1
419
+  (0.0ms) RELEASE SAVEPOINT active_record_1
420
+  (0.1ms) rollback transaction
421
+  (0.4ms) begin transaction
422
+  (0.0ms) rollback transaction
423
+  (0.1ms) begin transaction
424
+  (0.1ms) rollback transaction
425
+  (0.1ms) begin transaction
426
+  (0.1ms) SAVEPOINT active_record_1
427
+ SQL (19.7ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:56:31 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:56:31 UTC +00:00]]
428
+  (0.1ms) RELEASE SAVEPOINT active_record_1
429
+  (0.2ms) rollback transaction
430
+  (0.1ms) begin transaction
431
+  (0.0ms) SAVEPOINT active_record_1
432
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:56:31 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:56:31 UTC +00:00]]
433
+  (0.0ms) RELEASE SAVEPOINT active_record_1
434
+  (0.1ms) rollback transaction
435
+  (0.0ms) begin transaction
436
+  (0.0ms) SAVEPOINT active_record_1
437
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:56:31 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:56:31 UTC +00:00]]
438
+  (0.0ms) RELEASE SAVEPOINT active_record_1
439
+  (0.0ms) SAVEPOINT active_record_1
440
+  (0.3ms) UPDATE "products" SET "price_cents" = 3210, "currency" = 'EUR', "updated_at" = '2012-05-01 09:56:31.561775' WHERE "products"."id" = 1
441
+  (0.0ms) RELEASE SAVEPOINT active_record_1
442
+  (0.2ms) rollback transaction
443
+  (0.1ms) begin transaction
444
+  (0.0ms) SAVEPOINT active_record_1
445
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:56:31 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:56:31 UTC +00:00]]
446
+  (0.0ms) RELEASE SAVEPOINT active_record_1
447
+  (0.1ms) rollback transaction
448
+  (0.0ms) begin transaction
449
+  (0.0ms) SAVEPOINT active_record_1
450
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:56:31 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:56:31 UTC +00:00]]
451
+  (0.0ms) RELEASE SAVEPOINT active_record_1
452
+  (0.1ms) rollback transaction
453
+  (0.0ms) begin transaction
454
+  (0.0ms) SAVEPOINT active_record_1
455
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:56:31 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:56:31 UTC +00:00]]
456
+  (0.0ms) RELEASE SAVEPOINT active_record_1
457
+  (0.0ms) SAVEPOINT active_record_1
458
+  (0.1ms) ROLLBACK TO SAVEPOINT active_record_1
459
+  (0.1ms) SAVEPOINT active_record_1
460
+  (0.2ms) UPDATE "products" SET "price_cents" = 2000, "updated_at" = '2012-05-01 09:56:31.615413' WHERE "products"."id" = 1
461
+  (0.0ms) RELEASE SAVEPOINT active_record_1
462
+  (0.2ms) rollback transaction
463
+  (0.4ms) begin transaction
464
+  (0.0ms) rollback transaction
465
+  (0.0ms) begin transaction
466
+  (0.1ms) rollback transaction
467
+  (0.1ms) begin transaction
468
+  (0.1ms) SAVEPOINT active_record_1
469
+ SQL (4.5ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:58:41 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:58:41 UTC +00:00]]
470
+  (0.1ms) RELEASE SAVEPOINT active_record_1
471
+  (0.2ms) rollback transaction
472
+  (0.0ms) begin transaction
473
+  (0.0ms) SAVEPOINT active_record_1
474
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:58:41 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:58:41 UTC +00:00]]
475
+  (0.0ms) RELEASE SAVEPOINT active_record_1
476
+  (0.1ms) rollback transaction
477
+  (0.0ms) begin transaction
478
+  (0.0ms) SAVEPOINT active_record_1
479
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:58:41 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:58:41 UTC +00:00]]
480
+  (0.0ms) RELEASE SAVEPOINT active_record_1
481
+  (0.0ms) SAVEPOINT active_record_1
482
+  (0.3ms) UPDATE "products" SET "price_cents" = 3210, "currency" = 'EUR', "updated_at" = '2012-05-01 09:58:41.382431' WHERE "products"."id" = 1
483
+  (0.0ms) RELEASE SAVEPOINT active_record_1
484
+  (0.2ms) rollback transaction
485
+  (0.1ms) begin transaction
486
+  (0.0ms) SAVEPOINT active_record_1
487
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:58:41 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:58:41 UTC +00:00]]
488
+  (0.0ms) RELEASE SAVEPOINT active_record_1
489
+  (0.1ms) rollback transaction
490
+  (0.0ms) begin transaction
491
+  (0.0ms) SAVEPOINT active_record_1
492
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:58:41 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:58:41 UTC +00:00]]
493
+  (0.0ms) RELEASE SAVEPOINT active_record_1
494
+  (0.2ms) rollback transaction
495
+  (0.1ms) begin transaction
496
+  (0.0ms) SAVEPOINT active_record_1
497
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:58:41 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:58:41 UTC +00:00]]
498
+  (0.0ms) RELEASE SAVEPOINT active_record_1
499
+  (0.0ms) SAVEPOINT active_record_1
500
+  (0.1ms) ROLLBACK TO SAVEPOINT active_record_1
501
+  (0.0ms) SAVEPOINT active_record_1
502
+  (0.2ms) UPDATE "products" SET "price_cents" = 2000, "updated_at" = '2012-05-01 09:58:41.402104' WHERE "products"."id" = 1
503
+  (0.0ms) RELEASE SAVEPOINT active_record_1
504
+  (0.1ms) rollback transaction
505
+  (0.6ms) begin transaction
506
+  (0.0ms) rollback transaction
507
+  (0.0ms) begin transaction
508
+  (0.0ms) rollback transaction
509
+  (0.1ms) begin transaction
510
+  (0.1ms) SAVEPOINT active_record_1
511
+ SQL (4.5ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:59:49 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:59:49 UTC +00:00]]
512
+  (0.1ms) RELEASE SAVEPOINT active_record_1
513
+  (0.2ms) rollback transaction
514
+  (0.0ms) begin transaction
515
+  (0.0ms) SAVEPOINT active_record_1
516
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:59:49 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:59:49 UTC +00:00]]
517
+  (0.0ms) RELEASE SAVEPOINT active_record_1
518
+  (0.1ms) rollback transaction
519
+  (0.0ms) begin transaction
520
+  (0.0ms) SAVEPOINT active_record_1
521
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:59:49 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:59:49 UTC +00:00]]
522
+  (0.0ms) RELEASE SAVEPOINT active_record_1
523
+  (0.0ms) SAVEPOINT active_record_1
524
+  (0.3ms) UPDATE "products" SET "price_cents" = 3210, "currency" = 'EUR', "updated_at" = '2012-05-01 09:59:49.232173' WHERE "products"."id" = 1
525
+  (0.0ms) RELEASE SAVEPOINT active_record_1
526
+  (0.2ms) rollback transaction
527
+  (0.0ms) begin transaction
528
+  (0.0ms) SAVEPOINT active_record_1
529
+ SQL (0.4ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:59:49 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:59:49 UTC +00:00]]
530
+  (0.1ms) RELEASE SAVEPOINT active_record_1
531
+  (0.1ms) rollback transaction
532
+  (0.1ms) begin transaction
533
+  (0.0ms) SAVEPOINT active_record_1
534
+ SQL (0.3ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:59:49 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:59:49 UTC +00:00]]
535
+  (0.0ms) RELEASE SAVEPOINT active_record_1
536
+  (0.1ms) rollback transaction
537
+  (0.0ms) begin transaction
538
+  (0.0ms) SAVEPOINT active_record_1
539
+ SQL (0.2ms) INSERT INTO "products" ("bonus_cents", "created_at", "currency", "discount", "price_cents", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["bonus_cents", 200], ["created_at", Tue, 01 May 2012 09:59:49 UTC +00:00], ["currency", nil], ["discount", 150], ["price_cents", 3000], ["updated_at", Tue, 01 May 2012 09:59:49 UTC +00:00]]
540
+  (0.0ms) RELEASE SAVEPOINT active_record_1
541
+  (0.0ms) SAVEPOINT active_record_1
542
+  (0.1ms) ROLLBACK TO SAVEPOINT active_record_1
543
+  (0.1ms) SAVEPOINT active_record_1
544
+  (0.3ms) UPDATE "products" SET "price_cents" = 2000, "updated_at" = '2012-05-01 09:59:49.251905' WHERE "products"."id" = 1
545
+  (0.0ms) RELEASE SAVEPOINT active_record_1
546
+  (0.1ms) rollback transaction
@@ -9,15 +9,33 @@ describe MoneyRails::Monetizable do
9
9
  end
10
10
 
11
11
  it "attaches a Money object to model field" do
12
+ @product.price.should be_an_instance_of(Money)
13
+ end
14
+
15
+ it "returns the expected money amount as a Money object" do
12
16
  @product.price.should == Money.new(3000)
13
17
  end
14
18
 
15
- it "respects :target_name argument" do
19
+ it "assigns the correct value from a Money object" do
20
+ @product.price = Money.new(3210, "EUR")
21
+ @product.save.should be_true
22
+ @product.price_cents.should == 3210
23
+ end
24
+
25
+ it "respects :as argument" do
16
26
  @product.discount_value.should == Money.new(150)
17
27
  end
18
28
 
19
29
  it "overrides table currency with a field specific" do
20
30
  @product.bonus.currency.should == Money::Currency.find(:eur)
21
31
  end
32
+
33
+ it "uses numericality validation" do
34
+ @product.price_cents = "foo"
35
+ @product.save.should be_false
36
+
37
+ @product.price_cents = 2000
38
+ @product.save.should be_true
39
+ end
22
40
  end
23
41
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: money-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-04-21 00:00:00.000000000 Z
14
+ date: 2012-05-01 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: money
@@ -134,9 +134,14 @@ extra_rdoc_files: []
134
134
  files:
135
135
  - lib/money-rails.rb
136
136
  - lib/money-rails/railtie.rb
137
+ - lib/money-rails/active_record/monetizable.rb
137
138
  - lib/money-rails/version.rb
138
- - lib/money-rails/monetize.rb
139
+ - lib/money-rails/configuration.rb
140
+ - lib/money-rails/orms.rb
141
+ - lib/generators/money_rails/initializer_generator.rb
142
+ - lib/generators/templates/money.rb
139
143
  - spec/spec_helper.rb
144
+ - spec/config_spec.rb
140
145
  - spec/dummy/script/rails
141
146
  - spec/dummy/Rakefile
142
147
  - spec/dummy/db/schema.rb
@@ -176,8 +181,10 @@ files:
176
181
  - spec/dummy/public/favicon.ico
177
182
  - spec/dummy/public/500.html
178
183
  - spec/monetize_spec.rb
184
+ - CHANGELOG.md
179
185
  - LICENSE
180
186
  - README.md
187
+ - Rakefile
181
188
  - money-rails.gemspec
182
189
  homepage: https://github.com/RubyMoney/money
183
190
  licenses:
@@ -206,6 +213,7 @@ specification_version: 3
206
213
  summary: Money gem integration with Rails
207
214
  test_files:
208
215
  - spec/spec_helper.rb
216
+ - spec/config_spec.rb
209
217
  - spec/dummy/script/rails
210
218
  - spec/dummy/Rakefile
211
219
  - spec/dummy/db/schema.rb
@@ -1,69 +0,0 @@
1
- require 'active_support/concern'
2
- require 'active_support/core_ext/array/extract_options'
3
- require 'active_support/deprecation/reporting'
4
-
5
- module MoneyRails
6
- module Monetizable
7
- extend ActiveSupport::Concern
8
-
9
- module ClassMethods
10
- def monetize(field, *args)
11
- options = args.extract_options!
12
-
13
- # Stringify model field name
14
- subunit_name = field.to_s
15
-
16
- if options[:field_currency] || options[:target_name] ||
17
- options[:model_currency]
18
- ActiveSupport::Deprecation.warn("You are using the old " \
19
- "argument keys of monetize command! Instead use :as, " \
20
- ":with_currency or :with_model_currency")
21
- end
22
-
23
- # Model currency field name
24
- model_currency_name = options[:with_model_currency] ||
25
- options[:model_currency] || "currency"
26
-
27
- # Override Model and default currency
28
- field_currency_name = options[:with_currency] ||
29
- options[:field_currency] || nil
30
-
31
- name = options[:as] || options[:target_name] || nil
32
-
33
- # Form target name for the money backed ActiveModel field:
34
- # if a target name is provided then use it
35
- # if there is a "_cents" suffix then just remove it to create the target name
36
- # if none of the previous is the case then use a default suffix
37
- if name
38
- name = name.to_s
39
- elsif subunit_name =~ /_cents$/
40
- name = subunit_name.sub(/_cents$/, "")
41
- else
42
- # FIXME: provide a better default
43
- name = subunit_name << "_money"
44
- end
45
-
46
- class_eval do
47
- composed_of name.to_sym,
48
- :class_name => "Money",
49
- :mapping => [[subunit_name, "cents"], [model_currency_name, "currency_as_string"]],
50
- :constructor => Proc.new { |cents, currency|
51
- Money.new(cents || 0, field_currency_name || currency ||
52
- Money.default_currency)
53
- },
54
- :converter => Proc.new { |value|
55
- if value.respond_to?(:to_money)
56
- if field_currency_name
57
- value.to_money(field_currency_name)
58
- else
59
- value.to_money
60
- end
61
- else
62
- raise(ArgumentError, "Can't convert #{value.class} to Money")
63
- end
64
- }
65
- end
66
- end
67
- end
68
- end
69
- end