Class: State

Inherits:
ApplicationRecord show all
Defined in:
app/models/state.rb

Overview

== Schema Information

Table name: states
Database name: primary

id :integer not null, primary key
code :string(255) not null
country_iso3 :string(255) not null
name :string(255) not null
region :string

Indexes

index_states_on_code_and_country_iso3 (code,country_iso3) UNIQUE
index_states_on_country_iso3 (country_iso3)

Constant Summary collapse

MAIN_COUNTRIES_ISO3 =

Main countries iso3.

%w[USA CAN].freeze
US_CONTINENTAL_STATE_LIST =

Us continental state list.

%w[AL AR AZ CA CO CT DC DE FL GA IA ID IL IN KS KY LA MA MD ME MI MN MO MS MT NC ND NE NH NJ NM NV NY OH OK OR PA RI SC
SD TN TX UT VA VT WA WI WV WY].freeze
CA_MAIN_PROVINCES =

Ca main provinces.

%w[AB BC MB NB NS ON QC SK].freeze
CONTINENTAL_REGION_CODES =

Continental region codes.

[] + US_CONTINENTAL_STATE_LIST + CA_MAIN_PROVINCES

Constants included from Schedulable

Schedulable::SIMPLE_FORM_OPTIONS

Instance Attribute Summary collapse

Has many collapse

Belongs to collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#codeObject (readonly)



41
# File 'app/models/state.rb', line 41

validates :code, uniqueness: { scope: :country_iso3 }

#country_iso3Object (readonly)



42
# File 'app/models/state.rb', line 42

validates :name, :code, :country_iso3, presence: true

#nameObject (readonly)



42
# File 'app/models/state.rb', line 42

validates :name, :code, :country_iso3, presence: true

Class Method Details

.by_countryActiveRecord::Relation<State>

A relation of States that are by country. Active Record Scope

Returns:

  • (ActiveRecord::Relation<State>)

See Also:



38
# File 'app/models/state.rb', line 38

scope :by_country, ->(country_iso3) { where(country_iso3: country_iso3.upcase) }

.by_country_isoActiveRecord::Relation<State>

A relation of States that are by country iso. Active Record Scope

Returns:

  • (ActiveRecord::Relation<State>)

See Also:



39
# File 'app/models/state.rb', line 39

scope :by_country_iso, ->(country_iso) { joins(:country).where(countries: { iso: country_iso.upcase }) }

.canadaActiveRecord::Relation<State>

A relation of States that are canada. Active Record Scope

Returns:

  • (ActiveRecord::Relation<State>)

See Also:



37
# File 'app/models/state.rb', line 37

scope :canada, -> { where(country_iso3: 'CAN') }

.code_for_string(str, countries_iso3: MAIN_COUNTRIES_ISO3) ⇒ Object

Looks up the state code for the given state name string.
Searches through the given list of country ISO3 codes.
Returns nil if no match found.



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/models/state.rb', line 123

def self.code_for_string(str, countries_iso3: MAIN_COUNTRIES_ISO3)
  return nil if str.blank?

  subdivision_name = str.strip.upcase
  code = nil
  countries_iso3.each do |iso3|
    next unless (c = ISO3166::Country.find_country_by_alpha3(iso3))

    # This code finder is case sensitive so doing our own
    # code = c.find_subdivision_by_name(str)&.code
    code = c.subdivisions.find do |sub_code, sub|
      sub_code.upcase == subdivision_name ||
        sub.name.upcase == subdivision_name ||
        [sub.unofficial_names].flatten.compact.any? { |n| n&.upcase == subdivision_name }
    end&.first
    break if code
  end
  # if no matches, try our internal table
  code ||= State.where(country_iso3: countries_iso3).where(State[:name].matches(str, nil, false)).first
  code
end

.options_for_shipping_ratesObject

Returns a list of state name/code pairs for all states except
territories, sorted by region, for use in shipping rate options.



113
114
115
116
117
118
# File 'app/models/state.rb', line 113

def self.options_for_shipping_rates
  # .insert(-1,%w[CONTINENTAL CONTINENTAL])
  where.not(region: 'US - Territories').sort_by(&:region).to_a.map do |c|
    ["#{c.name} - #{c.region.split(' - ').second}", c.code]
  end
end

.sortedActiveRecord::Relation<State>

A relation of States that are sorted. Active Record Scope

Returns:

  • (ActiveRecord::Relation<State>)

See Also:



35
# File 'app/models/state.rb', line 35

scope :sorted, -> { order(:name) }

.state_ids_for_select(countries_iso: nil, grouped_by_country: false, locale: nil) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'app/models/state.rb', line 83

def self.state_ids_for_select(countries_iso: nil, grouped_by_country: false, locale: nil)
  locale ||= I18n.locale
  lang_code = locale.to_s.first(2)
  if countries_iso == :all
    grouped_by_country = true # force it otherwise makes no sense
    countries_iso = ISO3166::Country.codes
  elsif countries_iso.nil?
    countries_iso = %w[US CA]
  else
    countries_iso = [countries_iso].flatten.compact
  end
  grouped = {}
  ungrouped = countries_iso.flat_map do |iso|
    iso3166_country = if iso.size == 2
                        ISO3166::Country[iso]
                      elsif iso.size == 3
                        ISO3166::Country.find_country_by_alpha3(iso)
                      end
    next unless iso3166_country

    states_array = iso3166_country.subdivisions.map { |k, v| [v.translations[lang_code] || k, State.where(code: k).first&.id] } || []
    grouped_country_name = iso3166_country.translations[lang_code] || iso3166_country.iso_short_name
    grouped[grouped_country_name] = states_array unless states_array.empty?
    states_array
  end
  grouped_by_country ? grouped : ungrouped
end

.states_for_select(countries_iso: nil, grouped_by_country: false, locale: nil) ⇒ Object

Returns a list of states grouped by country or ungrouped,
filtered by the provided country ISO codes.

countries_iso - An array of country ISO codes to filter states by.
Default is ['US', 'CA']. Pass :all for all countries.
grouped_by_country - Whether to group states by country or return a flat list.
locale - The locale to use for country or state names. Defaults to I18n.locale.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'app/models/state.rb', line 55

def self.states_for_select(countries_iso: nil, grouped_by_country: false, locale: nil)
  locale ||= I18n.locale
  lang_code = locale.to_s.first(2)
  if countries_iso == :all
    grouped_by_country = true # force it otherwise makes no sense
    countries_iso = ISO3166::Country.codes
  elsif countries_iso.nil?
    countries_iso = %w[US CA]
  else
    countries_iso = [countries_iso].flatten.compact
  end
  grouped = {}
  ungrouped = countries_iso.flat_map do |iso|
    iso3166_country = if iso.size == 2
                        ISO3166::Country[iso]
                      elsif iso.size == 3
                        ISO3166::Country.find_country_by_alpha3(iso)
                      end
    next unless iso3166_country

    states_array = iso3166_country.subdivisions.map { |k, v| [v.translations[lang_code] || k, k] } || []
    grouped_country_name = iso3166_country.translations[lang_code] || iso3166_country.iso_short_name
    grouped[grouped_country_name] = states_array unless states_array.empty?
    states_array
  end
  grouped_by_country ? grouped : ungrouped
end

.usaActiveRecord::Relation<State>

A relation of States that are usa. Active Record Scope

Returns:

  • (ActiveRecord::Relation<State>)

See Also:



36
# File 'app/models/state.rb', line 36

scope :usa, -> { where(country_iso3: 'USA') }

Instance Method Details

#countryCountry

Returns:

See Also:



33
# File 'app/models/state.rb', line 33

belongs_to :country, foreign_key: 'country_iso3', primary_key: 'iso3', optional: true

#tax_exemptionsActiveRecord::Relation<TaxExemption>

Returns:

See Also:



30
# File 'app/models/state.rb', line 30

has_many :tax_exemptions, foreign_key: 'state_code', primary_key: 'code'

#tax_ratesActiveRecord::Relation<TaxRate>

Returns:

  • (ActiveRecord::Relation<TaxRate>)

See Also:



31
# File 'app/models/state.rb', line 31

has_many :tax_rates, foreign_key: 'state_code', primary_key: 'code'

#to_sObject



44
45
46
# File 'app/models/state.rb', line 44

def to_s
  name
end