Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4. Country validation in model

I'm creating rails API and want to want to add validation for countries field which contains an ISO 3166-1 code on model level.

For example if use gem carmen-rails, it provides only helper country_select. Is that way to use validation for accordance country for ISO 3166-1 code in the model?

like image 601
Derk153 Avatar asked Dec 09 '22 07:12

Derk153


2 Answers

Here is the newest syntax for validation with the countries gem:

validates :country, inclusion: { in: ISO3166::Country.all.map(&:alpha2) }
like image 176
Spone Avatar answered Dec 24 '22 08:12

Spone


You are just trying to validate that the country code entered is appropriate? this should work with carmen

validates :country, inclusion: { in: Carmen::Country.all.map(&:code) }

But if this is all you need seems like the countries gem might work well too. With countries you could do

validates :country, inclusion: { in: Country.all.map(&:pop) }

Or

validate :country_is_iso_compliant

def country_is_iso_compliant
  errors.add(:country, "must be 2 characters (ISO 3166-1).") unless Country[country]
end

Update

For Region and State you can validate all 3 at the same time like this.

validates :country, :region, :state, presence: true
validate :location


def location
  current_country = Country[country]
  if current_country
    #valid regions would be something Like "Europe" or "Americas" or "Africa"  etc.
    errors.add(:region, "incorrect region for country #{current_country.name}.") unless current_country.region == region
    #this will work for short codes like "CA" or "01" etc.
    #for named states use current_country.states.map{ |k,v| v["name"}.include?(state)
    #which would work for "California" Or "Lusaka"(it's in Zambia learn something new every day)
    errors.add(:state, "incorrect state for country #{current_country.name}.") unless current_country.states.keys.include?(state)
  else
    errors.add(:country, "must be a 2 character country representation (ISO 3166-1).")
  end
end

Although Region seems unnecessary as you could imply this from the country like

before_validation {|record| record.region = Country[country].region if Country[country]}
 
like image 27
engineersmnky Avatar answered Dec 24 '22 08:12

engineersmnky