Search code examples
rubycurrencymoney-rails

Is it possible to filter list of Ruby money currencies to only active ones?


I'm using the money gem for currency conversions in a Rails app and need to generate a list of currencies for a form select tag.

The suggested documentation relies on getting calling Money::Currency.table to get a list of all currencies but this includes non iso currencies (e.g. Bitcoin) and old currencies (e.g. three invalid Zimbabwean Dollar entries).

Is there a way to only get a list of valid ISO currency codes without maintaining my own list?


Solution

  • The money gem does include separate lists, but unfortunately, they are merged together:

    def load_currencies
      currencies = parse_currency_file("currency_iso.json")
      currencies.merge! parse_currency_file("currency_non_iso.json")
      currencies.merge! parse_currency_file("currency_backwards_compatible.json")
    end
    

    You could invoke that code manually to obtain just the currency_iso.json list:

    Money::Currency.send(:parse_currency_file, 'currency_iso.json')
    #=> {
    #   :aed=>{:priority=>100, :iso_code=>"AED", :name=>"United Arab Emirates Dirham", :symbol=>"د.إ", :alternate_symbols=>["DH", "Dhs"], :subunit=>"Fils", :subunit_to_unit=>100, :symbol_first=>true, :html_entity=>"", :decimal_mark=>".", :thousands_separator=>",", :iso_numeric=>"784", :smallest_denomination=>25},
    #   :afn=>{:priority=>100, :iso_code=>"AFN", :name=>"Afghan Afghani", :symbol=>"؋", :alternate_symbols=>["Af", "Afs"], :subunit=>"Pul", :subunit_to_unit=>100, :symbol_first=>false, :html_entity=>"", :decimal_mark=>".", :thousands_separator=>",", :iso_numeric=>"971", :smallest_denomination=>100},
    #   :all=>{:priority=>100, :iso_code=>"ALL", :name=>"Albanian Lek", :symbol=>"L", :disambiguate_symbol=>"Lek", :alternate_symbols=>["Lek"], :subunit=>"Qintar", :subunit_to_unit=>100, :symbol_first=>false, :html_entity=>"", :decimal_mark=>".", :thousands_separator=>",", :iso_numeric=>"008", :smallest_denomination=>100},
    #   ...
    #   :zar=>{:priority=>100, :iso_code=>"ZAR", :name=>"South African Rand", :symbol=>"R", :alternate_symbols=>[], :subunit=>"Cent", :subunit_to_unit=>100, :symbol_first=>true, :html_entity=>"R", :decimal_mark=>".", :thousands_separator=>",", :iso_numeric=>"710", :smallest_denomination=>10},
    #   :zmk=>{:priority=>100, :iso_code=>"ZMK", :name=>"Zambian Kwacha", :symbol=>"ZK", :disambiguate_symbol=>"ZMK", :alternate_symbols=>[], :subunit=>"Ngwee", :subunit_to_unit=>100, :symbol_first=>false, :html_entity=>"", :decimal_mark=>".", :thousands_separator=>",", :iso_numeric=>"894", :smallest_denomination=>5},
    #   :zmw=>{:priority=>100, :iso_code=>"ZMW", :name=>"Zambian Kwacha", :symbol=>"ZK", :disambiguate_symbol=>"ZMW", :alternate_symbols=>[], :subunit=>"Ngwee", :subunit_to_unit=>100, :symbol_first=>false, :html_entity=>"", :decimal_mark=>".", :thousands_separator=>",", :iso_numeric=>"967", :smallest_denomination=>5}}
    # }
    

    Note however that this is a private method so it might change in future versions.