Class: Country

Inherits:
ApplicationRecord show all
Includes:
IdentityCache
Defined in:
app/models/country.rb

Overview

Schema Information

Table name: countries

id            :integer          not null, primary key
alpha2        :string(191)      not null
alpha3        :string(191)      not null
currency_code :string(191)
icon          :string(191)
name          :string(191)      not null

Indexes

index_countries_on_alpha3  (alpha3) UNIQUE
index_countries_on_name    (name)

Constant Summary collapse

THAI_CURRENCY_CODE =

Constants

'THB'.freeze
SINGAPORE_CURRENCY_CODE =
'SGD'.freeze
MALAYSIA_CURRENCY_CODE =
'MYR'.freeze
USA_CURRENCY_CODE =
'USD'.freeze
CENT_CONVERSION_RATE =

Conversion rate for currencies that use cent-based points (SGD, MYR) 1 point = 0.01 currency unit (e.g., 100 points = 1.00 SGD/MYR)

0.01

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ApplicationRecord

sync_carrierwave_url

Class Method Details

.convert_points_to_currency(points, currency_code = THAI_CURRENCY_CODE) ⇒ Float, Integer

Note:

Converts raw points into displayable currency value based on currency code.

If the currency is Singapore Dollar (SGD) or Malaysian Ringgit (MYR), the method converts the raw points into a decimal value by applying the cent conversion rate (e.g., 100 points → 1.0). For other currencies (default: Thai Baht - THB), the points are returned as-is.

  • This method assumes that SGD and MYR points are stored as “cents” (i.e., 1 point = CENT_CONVERSION_RATE currency unit).

  • Rounding is applied to 2 decimal places for SGD and MYR to ensure monetary precision.

Examples:

Country.convert_points_to_currency(100, 'SGD') # => 1.0
Country.convert_points_to_currency(100, 'MYR') # => 1.0
Country.convert_points_to_currency(150, 'THB') # => 150
Country.convert_points_to_currency(255, 'SGD') # => 2.55

Parameters:

  • points (Integer, Float)

    The raw point amount to be converted.

  • currency_code (String) (defaults to: THAI_CURRENCY_CODE)

    The currency code (e.g., “THB”, “SGD”, “MYR”). Defaults to “THB”.

Returns:

  • (Float, Integer)

    The converted point value based on the currency. Returns Float (rounded to 2 decimals) for SGD/MYR, Integer for THB.



120
121
122
123
124
125
126
127
128
# File 'app/models/country.rb', line 120

def convert_points_to_currency(points, currency_code = THAI_CURRENCY_CODE)
  currency_upcase = currency_code.to_s.upcase
  case currency_upcase
  when SINGAPORE_CURRENCY_CODE, MALAYSIA_CURRENCY_CODE
    (points * CENT_CONVERSION_RATE).round(2)
  else
    points
  end
end

.find_malaysiaObject



63
64
65
66
67
# File 'app/models/country.rb', line 63

def find_malaysia
  Rails.cache.fetch('Country:find_malaysia', expires_in: 1.year) do
    find_or_create_by(name: 'Malaysia', alpha3: 'MYS', alpha2: 'MY')
  end
end

.find_singaporeObject



57
58
59
60
61
# File 'app/models/country.rb', line 57

def find_singapore
  Rails.cache.fetch('Country:find_singapore', expires_in: 1.year) do
    find_or_create_by(name: 'Singapore', alpha3: 'SGP', alpha2: 'SG')
  end
end

.find_thailandObject



51
52
53
54
55
# File 'app/models/country.rb', line 51

def find_thailand
  Rails.cache.fetch('Country:find_thailand', expires_in: 1.year) do
    find_or_create_by(name: 'Thailand', alpha3: 'THA', alpha2: 'TH')
  end
end

.valid_countriesArray<Country>

Note:

Retrieves a list of valid countries from the database and caches the result.

This method returns only countries with names “Thailand”, “Singapore”, and “Malaysia”, ordered as Thailand, Singapore, Malaysia. The result is cached under the key `'Country:valid_countries'` for 1 year to minimize unnecessary database queries.

  • The result is cached for 1 year, so updates to the Country records (e.g., name changes) will not take effect until the cache is expired or manually cleared.

  • This method is currently used only in the “Give point manually” menu to provide currency/country selection when assigning points manually to a user.

  • Ordering is based on ApiV5::Constants::COUNTRY_CODES array order.

  • Uses MySQL FIELD() function for database-level ordering, which is more efficient than Ruby-level sorting for small datasets.

Examples:

Country.valid_countries
# => [#<Country id: 218, name: "Thailand">, #<Country id: 198, name: "Singapore">, #<Country id: 127, name: "Malaysia">]

Returns:

  • (Array<Country>)

    A collection of Country records ordered by COUNTRY_CODES.



89
90
91
92
93
94
95
96
97
98
# File 'app/models/country.rb', line 89

def valid_countries
  Rails.cache.fetch('Country:valid_countries', expires_in: 1.year) do
    codes = ApiV5::Constants::COUNTRY_CODES
    # Use connection.quote to safely escape each code value
    quoted_codes = codes.map { |code| connection.quote(code) }.join(', ')
    where(alpha3: codes).order(
      Arel.sql("FIELD(alpha3, #{quoted_codes})"),
    ).to_a
  end
end

.valid_country_code?(country_alpha3) ⇒ Boolean

Checks if the given country alpha3 code exists in the database.

Examples:

Country.valid_country_code?("THA")  # => true
Country.valid_country_code?("SGP")  # => true
Country.valid_country_code?("IDN")  # => true
Country.valid_country_code?("XYZ")  # => false

Parameters:

  • country_alpha3 (String)

    The alpha3 code of the country to check (e.g., “THA” for Thailand, “SGP” for Singapore, “USA” for United States of America, etc.)

Returns:

  • (Boolean)

    true if the country exists, false otherwise.



140
141
142
143
144
145
146
# File 'app/models/country.rb', line 140

def valid_country_code?(country_alpha3)
  return false if country_alpha3.blank?

  Rails.cache.fetch("country_alpha3_exists/#{country_alpha3}", expires_in: 1.year) do
    Country.exists?(alpha3: country_alpha3)
  end
end

Instance Method Details

#country_code_downcaseObject

Returns the alpha3 code of the country in lowercase.



155
156
157
# File 'app/models/country.rb', line 155

def country_code_downcase
  alpha3.downcase
end

#currency_code_upcaseObject

Returns the currency_code of the country in uppercase.



150
151
152
# File 'app/models/country.rb', line 150

def currency_code_upcase
  currency_code.upcase
end