Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby Ruby Foundations Numbers Currency

Using the gem "Money", it will not allow me to use "puts price"

irb(main):007:0> require "Money"
=> true
irb(main):008:0> price = Money.new(1000)
=> #<Money fractional:1000 currency:USD>
irb(main):009:0> puts price
I18n::InvalidLocale: :en is not a valid locale
    from /Users/Leung/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/i18n-0.7.0.beta1/lib/i18n.rb:284:in `enforce_available_locales!'
    from /Users/Leung/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/i18n-0.7.0.beta1/lib/i18n.rb:151:in `translate'
    from /Users/Leung/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/money-6.2.1/lib/money/money/formatting.rb:17:in `block in define_i18n_method'
    from /Users/Leung/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/money-6.2.1/lib/money/money.rb:346:in `to_s'
    from (irb):9:in `puts'
    from (irb):9:in `puts'
    from (irb):9
    from /Users/Leung/.rbenv/versions/2.1.2/bin/irb:11:in `<main>'
John Stoveld
John Stoveld
4,203 Points

Looks like this is still plaguing users.

Just got the same problem

I18n::InvalidLocale: :en is not a valid locale from /Users/JS/.rvm/gems/ruby-2.2.0/gems/i18n-0.7.0/lib/i18n.rb:284:in enforce_available_locales!' from /Users/JS/.rvm/gems/ruby-2.2.0/gems/i18n-0.7.0/lib/i18n.rb:151:intranslate' from /Users/JS/.rvm/gems/ruby-2.2.0/gems/money-6.5.0/lib/money/money/formatting.rb:17:in block in define_i18n_method' from /Users/JS/.rvm/gems/ruby-2.2.0/gems/money-6.5.0/lib/money/money.rb:382:into_s' from (irb):10:in puts' from (irb):10:inputs' from (irb):10 from /Users/JS/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `<main>' 2.2.0 :011 >

12 Answers

Antoine Boillot
Antoine Boillot
10,466 Points

Hi all,

Following Alyssa Argento's answer and adding to it a few searches on the web, I managed to fix the issue permanently.

First, as a reminder, here is the error message I got (quite similar to the one of Tery Leung) :

2.1.3 :005 > puts price.to_s
I18n::InvalidLocale: :en is not a valid locale
    from /Users/Antoine/.rvm/gems/ruby-2.1.3/gems/i18n-0.7.0.beta1/lib/i18n.rb:284:in `enforce_available_locales!'
    from /Users/Antoine/.rvm/gems/ruby-2.1.3/gems/i18n-0.7.0.beta1/lib/i18n.rb:151:in `translate'
    from /Users/Antoine/.rvm/gems/ruby-2.1.3/gems/money-6.3.0/lib/money/money/formatting.rb:17:in `block in define_i18n_method'
    from /Users/Antoine/.rvm/gems/ruby-2.1.3/gems/money-6.3.0/lib/money/money.rb:366:in `to_s'
    from (irb):5
    from /Users/Antoine/.rvm/rubies/ruby-2.1.3/bin/irb:11:in `<main>'

I then decided to look at the i18n directory (the path could be different for you, I just copied and pasted the one of my error message) :

$ cd /Users/Antoine/.rvm/gems/ruby-2.1.3/gems/i18n-0.7.0.beta1/lib/i18n
$ ls
backend     core_ext    gettext.rb  locale.rb   version.rb
backend.rb  exceptions.rb   interpolate tests
config.rb   gettext     locale      tests.rb

I opened the "config.rb" file in Sublime Text :

$ subl config.rb

On line 131, I changed the following code :

@@enforce_available_locales = true

To

@@enforce_available_locales = false

I then saved and closed the file.

BE CAREFUL NOT TO CHANGE ANYTHING ELSE !!!

Back to IRB, I followed Jason's step by step process and it worked :

2.1.3 :001 > require 'money'
 => true 
2.1.3 :002 > price = Money.new(1000)
 => #<Money fractional:1000 currency:USD> 
2.1.3 :003 > puts price.to_s
10.00
 => nil 
2.1.3 :004 > 

Hope this helps,

Cheers,

Worked for me, thanks!

...though it feels a bit weird to change config. I commented it though, so that way I can know what I did later. :smiley:

I'm having the problem too. However, I'm using the treehouse VM. How might I go about your fix using a VM instead of having ruby installed on my machine?

Antoine Boillot
Antoine Boillot
10,466 Points

Hi Michael,

I'm quite surprise you encountering the issue using the VM. No idea on how to solve this in that context. I suggest you contact support.

Sorry not be more helpful,

Cheers,

Matthew Thompson
Matthew Thompson
4,500 Points

This works a treat, thanks

Thanks Antoine, your fix worked perfectly for me!

Yes the fix works, thanks. I believe that more documentation on why this error exists can be found at: https://stackoverflow.com/questions/20361428/rails-i18n-validation-deprecation-warning

Unfortunately, since I'm just a beginner, I don't understand the explanations therein. :P

You are a beast! thank you

David Rynn
David Rynn
10,554 Points

I had the same issue on both my Mac (which gave me a nearly identical error message) and with my PC. I followed the advice of the error on my PC and it worked. I simply put into the irb I18n.enforce_available_locales = false and that did the trick. See below for more detail:

irb(main):002:0> require 'money'
=> true
irb(main):003:0> price = Money.new(1000)
=> #<Money fractional:1000 currency:USD>
irb(main):004:0> price = Money.new(1000, "USD")
=> #<Money fractional:1000 currency:USD>
irb(main):005:0> puts price
[deprecated] I18n.enforce_available_locales will default to true in the future.
If you really want to skip validation of your locale you can set I18n.enforce_av
ailable_locales = false to avoid this message.
10.00
=> nil
irb(main):006:0> I18n.enforce_available_locales = false
=> false
irb(main):007:0> puts price
10.00
=> nil
irb(main):008:0> Tada!
=> You are the man!
Gene Johnson
Gene Johnson
3,471 Points

Thanks. This is the only thing that worked for me. Running rbenv on OSX.

John Stoveld
John Stoveld
4,203 Points

This worked for me David +1 Ty.

WHY does it work?

Ron Chan
Ron Chan
10,987 Points

Thanks David. Works perfectly for me in cmd on Windows 8.1

After much searching and many wrong turns I have come up with something that could be akin to a (temporary?) fix until someone with far much Ruby wisdom than me enlightens us further.

The first thing you should do, and for many this should be enough, is, in the same way you have to call 'require' on money, you do also for 'i18n' as follows:

require 'i18n'

This should return 'true', and at this point your problem may be solved. If not however, proceed to either of the two following steps. Try the one below first and then test if it has worked before moving on to the last option, and only if it hasn't worked should you move on to the last step.

I18n.enforce_available_locales = true
=> true #NB: This line shouldn't be typed, it is here purely to demonstrate what the return output from IRB should be.
I18n.default_locale = true

The above should solve the problem and persist through sessions if it does, unlike the following option which has been reported by some people to only persist for the current session.

I18n.enforce_available_locales = false
=> false # This should be the return value you get.
I18n.default_locale = :en
=> :en # This should be the return value you get.

Remember that you may need to enter the above code each time you start a new session. If so, always remember to call 'require' on both "money" and "i18n" each time, and before entering the above code.


Just for reference for any that might be interested, and are curious as to what I18n actually does (probably amongst other things) in relation to RubyMoney, is it aids in locale formatting for currency output. See the following excerpt from the RubyMoney API documentation for an example:

Money.new(123456789, "SEK").format

will return 1,234,567.89 kr which otherwise will return 1 234 567,89.

Hopefully this will be helpful to some, at least until we get some further guidance.

It looks like most of their examples include setting a currency when calling Money.new.

require 'money'

price = Money.new(1000, "USD")

Currencies are set using a string of the ISO 4217 currency codes (e.g. "USD" for US Dollars, "EUR" for Euros).

Tom Mertz
Tom Mertz
15,254 Points

Yeah I don't get any errors if I use this method. I think Money just wants people to start specifying the locality of the currency, so they are warning people that setting a money object without a currency type in the future will give an error.

Thanks!

James Lees
James Lees
11,225 Points

Geoff and Tom, thanks for this. Note from my side, this only worked for me if I changed the default as outlined in previous posts. I Ran the following in irb (main),

I18n.enforce_available_locales = false

Then ensure you specify the currency as mentioned above, this worked for me.

Kang-Kyu Lee
Kang-Kyu Lee
52,045 Points

Maybe, maybe we can try

irb> require "money"

(lowercase) instead? or should have changed as using 'monetize' gem instead.

Kang-Kyu Lee
Kang-Kyu Lee
52,045 Points

documentation here http://rubymoney.github.io/money/ just in case

Edit: above document says USD is a default currency. Does this class have to_s method by the way? Edit: looks like it has to_s... wonder why didn't work http://rubydoc.info/gems/money/Money:to_s

Kang-Kyu Lee
Kang-Kyu Lee
52,045 Points

on the error message (I didn't read earlier) it said I18n::InvalidLocale: :en is not a valid locale. What if this is not a problem of money gem, your ruby might have a specific setup for i18n gem.

maybe this link helps http://ruby-i18n.org/wiki

I'm having the same issue:

2.1.2 :008 > price = Money.new(1000)
 => #<Money fractional:1000 currency:USD> 
2.1.2 :009 > puts price
I18n::InvalidLocale: :en is not a valid locale
    from /home/y/.rvm/gems/ruby-2.1.2/gems/i18n-0.7.0.beta1/lib/i18n.rb:284:in `enforce_available_locales!'
    from /home/y/.rvm/gems/ruby-2.1.2/gems/i18n-0.7.0.beta1/lib/i18n.rb:151:in `translate'
    from /home/y/.rvm/gems/ruby-2.1.2/gems/money-6.3.0/lib/money/money/formatting.rb:17:in `block in define_i18n_method'
    from /home/y/.rvm/gems/ruby-2.1.2/gems/money-6.3.0/lib/money/money.rb:366:in `to_s'
    from (irb):9:in `puts'
    from (irb):9:in `puts'
    from (irb):9
    from /home/y/.rvm/rubies/ruby-2.1.2/bin/irb:11:in `<main>'
Alexander Bromage
PLUS
Alexander Bromage
Courses Plus Student 4,014 Points

I am having the same problem but the solution above only works for that session. How do I solve the problem permanently?

Christ khodabakhshi
Christ khodabakhshi
10,916 Points

I had the same problem, I am not sure that is a good solution or not but, I convert it to float and it worked.

puts total.to_f

does is it have any problem?

Michael Branch :

Using the VM instead of having ruby installed locally shouldn't make the solution any different, from what I can tell (this used to confuse me, too).

Hope that helps!

I like some of the answer from Antoine Boillot, but I was unwilling to just comment lines in the i18n gem. Doing this seems like it would break everytime you upgraded your gem. Not a good behaviour. Reading up a little on what i18n was actually doing, I think I found a better solution. The problem is that locales are being forced and that we have no :en local defined. This can be fixed by installing and loading the rails-i18n gem.

$ gem install rails-i18n

This gem will give us our :en locale allow us to properly enforce locales. This has the added benefit of also providing numerous other locale files for future international development.


Now by following the example in the video, instead of this:

bash-4.3$ irb
irb(main):001:0> require "money"
    => true
irb(main):002:0> price = Money.new(1000)
    => #<Money fractional:1000 currency:USD>
irb(main):003:0> puts price
I18n::InvalidLocale: :en is not a valid locale
    from /usr/local/var/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/i18n-0.7.0/lib/i18n.rb:284:in `enforce_available_locales!'
    from /usr/local/var/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/i18n-0.7.0/lib/i18n.rb:151:in `translate'
    from /usr/local/var/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/money-6.5.0/lib/money/money/formatting.rb:17:in `block in define_i18n_method'
    from /usr/local/var/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/money-6.5.0/lib/money/money.rb:382:in `to_s'
    from (irb):3:in `puts'
    from (irb):3:in `puts'
    from (irb):3
    from /usr/local/var/rbenv/versions/2.2.0/bin/irb:11:in `<main>'
irb(main):004:0>

We have this:

bash-4.3$ irb
irb(main):001:0> require "rails-i18n"
    => true
irb(main):002:0> require "money"
    => true
irb(main):003:0> price = Money.new(1000)
    => #<Money fractional:1000 currency:USD>
irb(main):004:0> puts price
    10.00
    => nil
irb(main):005:0>

I would like to make a final note. When I was following along with the Installing Ruby on Mac, I found that using homebrew, instead of git directly, did better with managing permissions when adding gems. Using the technique in the movie, I had to use sudo. By using homebrew to install rbenv and ruby-build, gem can be used without sudo.

Randy Hamilton
Randy Hamilton
4,515 Points

I did a little research and at "https://github.com/RubyMoney/money#migration-notes" I found that you can disable i18n with the code Money.use_i18n = false and that seemed to work fine, although I am new to Ruby so let me know if I ended up disabling something important in the end!