money-rails 1.13.0 → 1.14.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.
@@ -1,8 +1,7 @@
1
1
  module MoneyRails
2
2
  module ActionViewExtension
3
-
4
- def currency_symbol
5
- content_tag(:span, Money.default_currency.symbol, class: "currency_symbol")
3
+ def currency_symbol(currency = Money.default_currency)
4
+ content_tag(:span, Money::Currency.find(currency).symbol, class: "currency_symbol")
6
5
  end
7
6
 
8
7
  def humanized_money(value, options={})
@@ -48,5 +47,13 @@ module MoneyRails
48
47
  def money_without_cents_and_with_symbol(value)
49
48
  money_without_cents(value, symbol: true)
50
49
  end
50
+
51
+ def money_only_cents(value)
52
+ return '00' unless value.respond_to?(:to_money)
53
+
54
+ value = value.to_money
55
+
56
+ format "%0#{value.currency.exponent}d", (value % value.currency.subunit_to_unit).cents
57
+ end
51
58
  end
52
59
  end
@@ -18,7 +18,13 @@ module MoneyRails
18
18
  else
19
19
  false
20
20
  end
21
- current_adapter = ::ActiveRecord::Base.connection_config[:adapter]
21
+
22
+ current_adapter = if ::ActiveRecord::Base.respond_to?(:connection_db_config)
23
+ ::ActiveRecord::Base.connection_db_config.configuration_hash[:adapter]
24
+ else
25
+ ::ActiveRecord::Base.connection_config[:adapter]
26
+ end
27
+
22
28
  postgresql_with_money = rails42 && PG_ADAPTERS.include?(current_adapter)
23
29
  end
24
30
  end
@@ -2,7 +2,7 @@ require "active_support/core_ext/module/aliasing.rb"
2
2
  require "active_support/core_ext/hash/reverse_merge.rb"
3
3
 
4
4
  class Money
5
- class <<self
5
+ class << self
6
6
  alias_method :orig_default_formatting_rules, :default_formatting_rules
7
7
 
8
8
  def default_formatting_rules
@@ -21,4 +21,9 @@ class Money
21
21
  rules
22
22
  end
23
23
  end
24
+
25
+ # This is expected to be called by ActiveSupport when calling as_json an Money object
26
+ def to_hash
27
+ { cents: cents, currency_iso: currency.iso_code.to_s }
28
+ end
24
29
  end
@@ -28,25 +28,12 @@ class Money
28
28
  # Takes any possible object and converts it to how it would be
29
29
  # stored in the database.
30
30
  def mongoize(object)
31
- case
32
- when object.is_a?(Money) then object.mongoize
33
- when object.is_a?(Hash) then
34
- if object.respond_to?(:deep_symbolize_keys!)
35
- object.deep_symbolize_keys!
36
- elsif object.respond_to?(:symbolize_keys!)
37
- object.symbolize_keys!
38
- end
39
- ::Money.new(object[:cents], object[:currency_iso]).mongoize
40
- when object.nil? then nil
41
- when object.respond_to?(:to_money) then
42
- begin
43
- object.to_money.mongoize
44
- rescue Money::Currency::UnknownCurrency, Monetize::ParseError => e
45
- raise MoneyRails::Error, e.message if MoneyRails.raise_error_on_money_parsing
46
- nil
47
- end
48
- else object
49
- end
31
+ return object.mongoize if object.is_a?(Money)
32
+ return mongoize_hash(object) if object.is_a?(Hash)
33
+ return nil if object.nil?
34
+ return mongoize_castable(object) if object.respond_to?(:to_money)
35
+
36
+ object
50
37
  end
51
38
 
52
39
  # Converts the object that was supplied to a criteria and converts it
@@ -57,5 +44,27 @@ class Money
57
44
  else object
58
45
  end
59
46
  end
47
+
48
+ private
49
+
50
+ def mongoize_hash(hash)
51
+ if hash.respond_to?(:deep_symbolize_keys!)
52
+ hash.deep_symbolize_keys!
53
+ elsif hash.respond_to?(:symbolize_keys!)
54
+ hash.symbolize_keys!
55
+ end
56
+
57
+ # Guard for a blank form
58
+ return nil if hash[:cents] == '' && hash[:currency_iso] == ''
59
+
60
+ ::Money.new(hash[:cents], hash[:currency_iso]).mongoize
61
+ end
62
+
63
+ def mongoize_castable(object)
64
+ object.to_money.mongoize
65
+ rescue Money::Currency::UnknownCurrency, Monetize::ParseError => e
66
+ return nil unless MoneyRails.raise_error_on_money_parsing
67
+ raise MoneyRails::Error, e.message
68
+ end
60
69
  end
61
70
  end
@@ -8,7 +8,7 @@ module RailsAdmin
8
8
  module Config
9
9
  module Fields
10
10
  module Types
11
- class Money < RailsAdmin::Config::Fields::Types::Integer
11
+ class Money < RailsAdmin::Config::Fields::Types::Decimal
12
12
  RailsAdmin::Config::Fields::Types::register(self)
13
13
 
14
14
  register_instance_option :pretty_value do
@@ -1,6 +1,6 @@
1
1
  module MoneyRails
2
2
  class Railtie < ::Rails::Railtie
3
- initializer 'moneyrails.initialize' do
3
+ initializer 'moneyrails.initialize', after: 'active_record.initialize_database' do
4
4
  MoneyRails::Hooks.init
5
5
  end
6
6
  end
@@ -1,3 +1,3 @@
1
1
  module MoneyRails
2
- VERSION = '1.13.0'
2
+ VERSION = '1.14.0'
3
3
  end
data/money-rails.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
26
26
 
27
27
  s.require_path = "lib"
28
28
 
29
- s.add_dependency "money", "~> 6.13.0"
29
+ s.add_dependency "money", "~> 6.13.2"
30
30
  s.add_dependency "monetize", "~> 1.9.0"
31
31
  s.add_dependency "activesupport", ">= 3.0"
32
32
  s.add_dependency "railties", ">= 3.0"
@@ -36,4 +36,11 @@ Gem::Specification.new do |s|
36
36
  s.add_development_dependency "rspec-rails", "~> 3.0"
37
37
  s.add_development_dependency 'database_cleaner', '~> 1.6.1'
38
38
  s.add_development_dependency 'test-unit', '~> 3.0' if RUBY_VERSION >= '2.2'
39
+ s.add_development_dependency 'bundler'
40
+
41
+ if s.respond_to?(:metadata)
42
+ s.metadata['changelog_uri'] = 'https://github.com/RubyMoney/money-rails/blob/master/CHANGELOG.md'
43
+ s.metadata['source_code_uri'] = 'https://github.com/RubyMoney/money-rails/'
44
+ s.metadata['bug_tracker_uri'] = 'https://github.com/RubyMoney/money-rails/issues'
45
+ end
39
46
  end
@@ -20,6 +20,14 @@ if defined? ActiveRecord
20
20
  Service.create(charge_cents: 2000, discount_cents: 120)
21
21
  end
22
22
 
23
+ def update_product(*attributes)
24
+ if defined?(::ActiveRecord::VERSION) && ::ActiveRecord::VERSION::MAJOR >= 5
25
+ product.update(*attributes)
26
+ else
27
+ product.update_attributes(*attributes)
28
+ end
29
+ end
30
+
23
31
  context ".monetized_attributes" do
24
32
 
25
33
  class InheritedMonetizeProduct < Product
@@ -73,7 +81,7 @@ if defined? ActiveRecord
73
81
  end
74
82
 
75
83
  it "correctly updates from a Money object using update_attributes" do
76
- expect(product.update_attributes(price: Money.new(215, "USD"))).to be_truthy
84
+ expect(update_product(price: Money.new(215, "USD"))).to be_truthy
77
85
  expect(product.price_cents).to eq(215)
78
86
  end
79
87
 
@@ -187,8 +195,8 @@ if defined? ActiveRecord
187
195
  end
188
196
 
189
197
  it "respects numericality validation when using update_attributes" do
190
- expect(product.update_attributes(price_cents: "some text")).to be_falsey
191
- expect(product.update_attributes(price_cents: 2000)).to be_truthy
198
+ expect(update_product(price_cents: "some text")).to be_falsey
199
+ expect(update_product(price_cents: 2000)).to be_truthy
192
200
  end
193
201
 
194
202
  it "uses numericality validation on money attribute" do
@@ -415,8 +423,8 @@ if defined? ActiveRecord
415
423
  end
416
424
 
417
425
  it "respects numericality validation when using update_attributes on money attribute" do
418
- expect(product.update_attributes(price: "some text")).to be_falsey
419
- expect(product.update_attributes(price: Money.new(320, 'USD'))).to be_truthy
426
+ expect(update_product(price: "some text")).to be_falsey
427
+ expect(update_product(price: Money.new(320, 'USD'))).to be_truthy
420
428
  end
421
429
 
422
430
  it "uses i18n currency format when validating" do
@@ -494,31 +502,31 @@ if defined? ActiveRecord
494
502
  product.price = Money.new(2500, :USD)
495
503
  expect(product.save).to be_truthy
496
504
  expect(product.price.cents).to eq(2500)
497
- expect(product.price.currency_as_string).to eq("USD")
505
+ expect(product.price.currency.to_s).to eq("USD")
498
506
  end
499
507
 
500
508
  it "correctly assigns Fixnum objects to the attribute" do
501
509
  product.price = 25
502
510
  expect(product.save).to be_truthy
503
511
  expect(product.price.cents).to eq(2500)
504
- expect(product.price.currency_as_string).to eq("USD")
512
+ expect(product.price.currency.to_s).to eq("USD")
505
513
 
506
514
  service.discount = 2
507
515
  expect(service.save).to be_truthy
508
516
  expect(service.discount.cents).to eq(200)
509
- expect(service.discount.currency_as_string).to eq("EUR")
517
+ expect(service.discount.currency.to_s).to eq("EUR")
510
518
  end
511
519
 
512
520
  it "correctly assigns String objects to the attribute" do
513
521
  product.price = "25"
514
522
  expect(product.save).to be_truthy
515
523
  expect(product.price.cents).to eq(2500)
516
- expect(product.price.currency_as_string).to eq("USD")
524
+ expect(product.price.currency.to_s).to eq("USD")
517
525
 
518
526
  service.discount = "2"
519
527
  expect(service.save).to be_truthy
520
528
  expect(service.discount.cents).to eq(200)
521
- expect(service.discount.currency_as_string).to eq("EUR")
529
+ expect(service.discount.currency.to_s).to eq("EUR")
522
530
  end
523
531
 
524
532
  it "correctly assigns objects to a accessor attribute" do
@@ -532,57 +540,57 @@ if defined? ActiveRecord
532
540
  product.bonus = 25
533
541
  expect(product.save).to be_truthy
534
542
  expect(product.bonus.cents).to eq(2500)
535
- expect(product.bonus.currency_as_string).to eq("GBP")
543
+ expect(product.bonus.currency.to_s).to eq("GBP")
536
544
 
537
545
  service.charge = 2
538
546
  expect(service.save).to be_truthy
539
547
  expect(service.charge.cents).to eq(200)
540
- expect(service.charge.currency_as_string).to eq("USD")
548
+ expect(service.charge.currency.to_s).to eq("USD")
541
549
  end
542
550
 
543
551
  it "overrides default, model currency with the value of :with_currency in string assignments" do
544
552
  product.bonus = "25"
545
553
  expect(product.save).to be_truthy
546
554
  expect(product.bonus.cents).to eq(2500)
547
- expect(product.bonus.currency_as_string).to eq("GBP")
555
+ expect(product.bonus.currency.to_s).to eq("GBP")
548
556
 
549
557
  service.charge = "2"
550
558
  expect(service.save).to be_truthy
551
559
  expect(service.charge.cents).to eq(200)
552
- expect(service.charge.currency_as_string).to eq("USD")
560
+ expect(service.charge.currency.to_s).to eq("USD")
553
561
 
554
562
  product.lambda_price = "32"
555
563
  expect(product.save).to be_truthy
556
564
  expect(product.lambda_price.cents).to eq(3200)
557
- expect(product.lambda_price.currency_as_string).to eq("CAD")
565
+ expect(product.lambda_price.currency.to_s).to eq("CAD")
558
566
  end
559
567
 
560
568
  it "overrides default currency with model currency, in fixnum assignments" do
561
569
  product.discount_value = 5
562
570
  expect(product.save).to be_truthy
563
571
  expect(product.discount_value.cents).to eq(500)
564
- expect(product.discount_value.currency_as_string).to eq("USD")
572
+ expect(product.discount_value.currency.to_s).to eq("USD")
565
573
  end
566
574
 
567
575
  it "overrides default currency with model currency, in string assignments" do
568
576
  product.discount_value = "5"
569
577
  expect(product.save).to be_truthy
570
578
  expect(product.discount_value.cents).to eq(500)
571
- expect(product.discount_value.currency_as_string).to eq("USD")
579
+ expect(product.discount_value.currency.to_s).to eq("USD")
572
580
  end
573
581
 
574
582
  it "falls back to default currency, in fixnum assignments" do
575
583
  service.discount = 5
576
584
  expect(service.save).to be_truthy
577
585
  expect(service.discount.cents).to eq(500)
578
- expect(service.discount.currency_as_string).to eq("EUR")
586
+ expect(service.discount.currency.to_s).to eq("EUR")
579
587
  end
580
588
 
581
589
  it "falls back to default currency, in string assignments" do
582
590
  service.discount = "5"
583
591
  expect(service.save).to be_truthy
584
592
  expect(service.discount.cents).to eq(500)
585
- expect(service.discount.currency_as_string).to eq("EUR")
593
+ expect(service.discount.currency.to_s).to eq("EUR")
586
594
  end
587
595
 
588
596
  it "sets field to nil, in nil assignments if allow_nil is set" do
@@ -616,13 +624,13 @@ if defined? ActiveRecord
616
624
  context "for column with model currency:" do
617
625
  it "has default currency if not specified" do
618
626
  product = Product.create(sale_price_amount: 1234)
619
- product.sale_price.currency_as_string == 'USD'
627
+ product.sale_price.currency.to_s == 'USD'
620
628
  end
621
629
 
622
630
  it "is overridden by instance currency column" do
623
631
  product = Product.create(sale_price_amount: 1234,
624
632
  sale_price_currency_code: 'CAD')
625
- expect(product.sale_price.currency_as_string).to eq('CAD')
633
+ expect(product.sale_price.currency.to_s).to eq('CAD')
626
634
  end
627
635
 
628
636
  it 'can change currency of custom column' do
@@ -634,14 +642,14 @@ if defined? ActiveRecord
634
642
  sale_price_currency_code: 'USD'
635
643
  )
636
644
 
637
- expect(product.sale_price.currency_as_string).to eq('USD')
645
+ expect(product.sale_price.currency.to_s).to eq('USD')
638
646
 
639
647
  product.sale_price = Money.new 456, 'CAD'
640
648
  product.save
641
649
  product.reload
642
650
 
643
- expect(product.sale_price.currency_as_string).to eq('CAD')
644
- expect(product.discount_value.currency_as_string).to eq('USD')
651
+ expect(product.sale_price.currency.to_s).to eq('CAD')
652
+ expect(product.discount_value.currency.to_s).to eq('USD')
645
653
  end
646
654
  end
647
655
 
@@ -705,12 +713,12 @@ if defined? ActiveRecord
705
713
  transaction.amount = Money.new(2500, :eur)
706
714
  expect(transaction.save).to be_truthy
707
715
  expect(transaction.amount.cents).to eq(Money.new(2500, :eur).cents)
708
- expect(transaction.amount.currency_as_string).to eq("EUR")
716
+ expect(transaction.amount.currency.to_s).to eq("EUR")
709
717
  end
710
718
 
711
719
  it "uses default currency if a non Money object is assigned to the attribute" do
712
720
  transaction.amount = 234
713
- expect(transaction.amount.currency_as_string).to eq("USD")
721
+ expect(transaction.amount.currency.to_s).to eq("USD")
714
722
  end
715
723
 
716
724
  it "constructs the money object from the mapped method value" do
@@ -738,6 +746,8 @@ if defined? ActiveRecord
738
746
  end
739
747
  end
740
748
 
749
+ # TODO: these specs should mock locale_backend with expected values
750
+ # instead of manipulating it directly
741
751
  context "and an Italian locale" do
742
752
  around(:each) do |example|
743
753
  I18n.with_locale(:it) do
@@ -745,7 +755,7 @@ if defined? ActiveRecord
745
755
  end
746
756
  end
747
757
 
748
- context "when use_i18n is true" do
758
+ context "when using :i18n locale backend" do
749
759
  it "validates with the locale's decimal mark" do
750
760
  transaction.amount = "123,45"
751
761
  expect(transaction.valid?).to be_truthy
@@ -767,13 +777,13 @@ if defined? ActiveRecord
767
777
  end
768
778
  end
769
779
 
770
- context "when use_i18n is false" do
780
+ context "when using :currency locale backend" do
771
781
  around(:each) do |example|
772
782
  begin
773
- Money.use_i18n = false
783
+ Money.locale_backend = :currency
774
784
  example.run
775
785
  ensure
776
- Money.use_i18n = true
786
+ Money.locale_backend = :i18n
777
787
  end
778
788
  end
779
789
 
@@ -18,8 +18,8 @@ describe "configuration" do
18
18
  end
19
19
 
20
20
  it "sets no_cents_if_whole value for formatted output globally" do
21
- # Disable the usage of I18n (to avoid default symbols for :en)
22
- Money.use_i18n = false
21
+ # Enable formatting to depend only on currency (to avoid default symbols for :en)
22
+ Money.locale_backend = :currency
23
23
 
24
24
  value = Money.new(12345600, "EUR")
25
25
  mark = Money::Currency.find(:eur).decimal_mark
@@ -35,7 +35,7 @@ describe "configuration" do
35
35
 
36
36
  # Reset global settings
37
37
  MoneyRails.no_cents_if_whole = nil
38
- Money.use_i18n = true
38
+ Money.locale_backend = :i18n
39
39
  end
40
40
 
41
41
  it "sets symbol for formatted output globally" do
File without changes
@@ -1,60 +1,59 @@
1
- # encoding: UTF-8
2
1
  # This file is auto-generated from the current state of the database. Instead
3
2
  # of editing this file, please use the migrations feature of Active Record to
4
3
  # incrementally modify your database, and then regenerate this schema definition.
5
4
  #
6
- # Note that this schema.rb definition is the authoritative source for your
7
- # database schema. If you need to create the application database on another
8
- # system, you should be using db:schema:load, not running all the migrations
9
- # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10
- # you'll amass, the slower it'll run and the greater likelihood for issues).
5
+ # This file is the source Rails uses to define your schema when running `bin/rails
6
+ # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7
+ # be faster and is potentially less error prone than running all of your
8
+ # migrations from scratch. Old migrations may fail to apply correctly if those
9
+ # migrations use external dependencies or application code.
11
10
  #
12
11
  # It's strongly recommended that you check this file into your version control system.
13
12
 
14
- ActiveRecord::Schema.define(version: 20151026220420) do
13
+ ActiveRecord::Schema.define(version: 2015_10_26_220420) do
15
14
 
16
15
  create_table "dummy_products", force: :cascade do |t|
17
- t.string "currency"
18
- t.integer "price_cents"
16
+ t.string "currency"
17
+ t.integer "price_cents"
19
18
  t.datetime "created_at"
20
19
  t.datetime "updated_at"
21
20
  end
22
21
 
23
22
  create_table "products", force: :cascade do |t|
24
- t.integer "price_cents"
25
- t.integer "discount"
23
+ t.integer "price_cents"
24
+ t.integer "discount"
26
25
  t.datetime "created_at"
27
26
  t.datetime "updated_at"
28
- t.integer "bonus_cents"
29
- t.integer "optional_price_cents"
30
- t.integer "sale_price_amount", default: 0, null: false
31
- t.string "sale_price_currency_code"
32
- t.integer "price_in_a_range_cents"
33
- t.integer "validates_method_amount_cents"
34
- t.integer "aliased_cents"
35
- t.integer "delivery_fee_cents"
36
- t.integer "restock_fee_cents"
37
- t.integer "reduced_price_cents"
38
- t.string "reduced_price_currency"
39
- t.integer "special_price_cents"
40
- t.integer "lambda_price_cents"
41
- t.string "skip_validation_price_cents"
27
+ t.integer "bonus_cents"
28
+ t.integer "optional_price_cents"
29
+ t.integer "sale_price_amount", default: 0, null: false
30
+ t.string "sale_price_currency_code"
31
+ t.integer "price_in_a_range_cents"
32
+ t.integer "validates_method_amount_cents"
33
+ t.integer "aliased_cents"
34
+ t.integer "delivery_fee_cents"
35
+ t.integer "restock_fee_cents"
36
+ t.integer "reduced_price_cents"
37
+ t.string "reduced_price_currency"
38
+ t.integer "special_price_cents"
39
+ t.integer "lambda_price_cents"
40
+ t.string "skip_validation_price_cents"
42
41
  end
43
42
 
44
43
  create_table "services", force: :cascade do |t|
45
- t.integer "charge_cents"
46
- t.integer "discount_cents"
44
+ t.integer "charge_cents"
45
+ t.integer "discount_cents"
47
46
  t.datetime "created_at"
48
47
  t.datetime "updated_at"
49
48
  end
50
49
 
51
50
  create_table "transactions", force: :cascade do |t|
52
- t.integer "amount_cents"
53
- t.integer "tax_cents"
54
- t.string "currency"
51
+ t.integer "amount_cents"
52
+ t.integer "tax_cents"
53
+ t.string "currency"
55
54
  t.datetime "created_at"
56
55
  t.datetime "updated_at"
57
- t.integer "optional_amount_cents"
56
+ t.integer "optional_amount_cents"
58
57
  end
59
58
 
60
59
  end