module ISO3166::CountryClassMethods

Constants

FIND_BY_REGEX
SEARCH_TERM_FILTER_REGEX

Public Instance Methods

[](query) click to toggle source
# File lib/countries/country/class_methods.rb, line 64
def [](query)
  search(query)
end
all(&blk) click to toggle source
# File lib/countries/country/class_methods.rb, line 29
def all(&blk)
  blk ||= proc { |_alpha2, d| ISO3166::Country.new(d) }
  ISO3166::Data.cache.map(&blk)
end
Also aliased as: countries
all_names_with_codes(locale = 'en') click to toggle source
# File lib/countries/country/class_methods.rb, line 40
def all_names_with_codes(locale = 'en')
  Country.all.map do |c|
    lc = (c.translation(locale) || c.name)
    [lc.respond_to?('html_safe') ? lc.html_safe : lc, c.alpha2]
  end.sort
end
all_translated(locale = 'en') click to toggle source
# File lib/countries/country/class_methods.rb, line 36
def all_translated(locale = 'en')
  translations(locale).values
end
codes() click to toggle source
# File lib/countries/country/class_methods.rb, line 25
def codes
  ISO3166::Data.codes
end
countries(&blk)
Alias for: all
create_subdivisions(subdivision_data) click to toggle source
# File lib/countries/country/class_methods.rb, line 104
def create_subdivisions(subdivision_data)
  subdivision_data.each_with_object({}) do |(k, v), hash|
    hash[k] = Subdivision.new(v)
  end
end
find_all_by(attribute, val) click to toggle source
# File lib/countries/country/class_methods.rb, line 86
def find_all_by(attribute, val)
  attributes, lookup_value = parse_attributes(attribute, val)

  ISO3166::Data.cache.select do |_, v|
    country = Country.new(v)
    attributes.any? do |attr|
      Array(country.send(attr)).any? do |n|
        lookup_value === cached(n) { parse_value(n) }
      end
    end
  end
end
method_missing(method_name, *arguments) click to toggle source
Calls superclass method
# File lib/countries/country/class_methods.rb, line 68
def method_missing(method_name, *arguments)
  matches = method_name.to_s.match(FIND_BY_REGEX)
  return_all = matches[1]
  super unless matches

  countries = find_by(matches[3], arguments[0], matches[2])
  return_all ? countries : countries.last
end
new(country_data) click to toggle source
Calls superclass method
# File lib/countries/country/class_methods.rb, line 21
def new(country_data)
  super if country_data.is_a?(Hash) || codes.include?(country_data.to_s.upcase)
end
respond_to_missing?(method_name, include_private = false) click to toggle source
Calls superclass method
# File lib/countries/country/class_methods.rb, line 77
def respond_to_missing?(method_name, include_private = false)
  matches = method_name.to_s.match(FIND_BY_REGEX)
  if matches && matches[3]
    matches[3].all? { |a| instance_methods.include?(a.to_sym) }
  else
    super
  end
end
subdivisions(alpha2) click to toggle source
# File lib/countries/country/class_methods.rb, line 99
def subdivisions(alpha2)
  @subdivisions ||= {}
  @subdivisions[alpha2] ||= create_subdivisions(subdivision_data(alpha2))
end
translations(locale = 'en') click to toggle source
# File lib/countries/country/class_methods.rb, line 47
def translations(locale = 'en')
  i18n_data_countries = I18nData.countries(locale.upcase)

  custom_countries = (ISO3166::Data.codes - i18n_data_countries.keys).map do |code|
    country = ISO3166::Country[code]
    translation = country.translations[locale] || country.name
    [code, translation]
  end.to_h

  i18n_data_countries.merge(custom_countries)
end

Protected Instance Methods

cached(value) { || ... } click to toggle source

Some methods like parse_value are expensive in that they create a large number of objects internally. In order to reduce the object creations and save the GC, we can cache them in an class instance variable. This will make subsequent parses O(1) and will stop the creation of new String object instances.

NB: We only want to use this cache for values coming from the JSON file or our own code, caching user-generated data could be dangerous since the cache would continually grow.

# File lib/countries/country/class_methods.rb, line 170
def cached(value)
  @_parsed_values_cache ||= {}
  return @_parsed_values_cache[value] if @_parsed_values_cache[value]
  @_parsed_values_cache[value] = yield
end
find_by(attribute, value, obj = nil) click to toggle source
# File lib/countries/country/class_methods.rb, line 141
def find_by(attribute, value, obj = nil)
  find_all_by(attribute.downcase, value).map do |country|
    obj.nil? ? country : new(country.last)
  end
end
parse_attributes(attribute, val) click to toggle source
# File lib/countries/country/class_methods.rb, line 120
def parse_attributes(attribute, val)
  raise "Invalid attribute name '#{attribute}'" unless searchable_attribute?(attribute.to_sym)

  attributes = Array(attribute.to_s)
  if attributes == ['name']
    attributes << 'unofficial_names'
    # TODO: Revisit when better data from i18n_data
    # attributes << 'translated_names'
  end

  [attributes, parse_value(val)]
end
parse_value(value) click to toggle source
# File lib/countries/country/class_methods.rb, line 147
def parse_value(value)
  value = value.gsub(SEARCH_TERM_FILTER_REGEX, '') if value.respond_to?(:gsub)
  strip_accents(value)
end
searchable_attribute?(attribute) click to toggle source
# File lib/countries/country/class_methods.rb, line 133
def searchable_attribute?(attribute)
  searchable_attributes.include?(attribute.to_sym)
end
searchable_attributes() click to toggle source
# File lib/countries/country/class_methods.rb, line 137
def searchable_attributes
  instance_methods - UNSEARCHABLE_METHODS
end
strip_accents(v) click to toggle source
# File lib/countries/country/class_methods.rb, line 112
def strip_accents(v)
  if v.is_a?(Regexp)
    Regexp.new(v.source.unaccent, 'i')
  else
    v.to_s.unaccent.downcase
  end
end
subdivision_data(alpha2) click to toggle source
# File lib/countries/country/class_methods.rb, line 152
def subdivision_data(alpha2)
  file = subdivision_file_path(alpha2)
  File.exist?(file) ? YAML.load_file(file) : {}
end
subdivision_file_path(alpha2) click to toggle source
# File lib/countries/country/class_methods.rb, line 157
def subdivision_file_path(alpha2)
  File.join(File.dirname(__FILE__), '..', 'data', 'subdivisions', "#{alpha2}.yaml")
end