【发布时间】:2014-07-31 11:11:38
【问题描述】:
我正在创建 Rails API,并希望为包含模型级别 ISO 3166-1 代码的国家/地区字段添加验证。
例如,如果使用 gem carmen-rails,它只提供 helper country_select。这种方式是对模型中的 ISO 3166-1 代码使用符合国家/地区的验证吗?
【问题讨论】:
标签: ruby-on-rails ruby validation ruby-on-rails-4 model
我正在创建 Rails API,并希望为包含模型级别 ISO 3166-1 代码的国家/地区字段添加验证。
例如,如果使用 gem carmen-rails,它只提供 helper country_select。这种方式是对模型中的 ISO 3166-1 代码使用符合国家/地区的验证吗?
【问题讨论】:
标签: ruby-on-rails ruby validation ruby-on-rails-4 model
这是使用countries gem 进行验证的最新语法:
validates :country, inclusion: { in: ISO3166::Country.all.map(&:alpha2) }
【讨论】:
您只是想验证输入的国家代码是否合适?这应该适用于carmen
validates :country, inclusion: { in: Carmen::Country.all.map(&:code) }
但是,如果这就是您所需要的,那么 countries gem 可能也能很好地工作。使用countries 你可以这样做
validates :country, inclusion: { in: Country.all.map(&:pop) }
或者
validate :country_is_iso_compliant
def country_is_iso_compliant
errors.add(:country, "must be 2 characters (ISO 3166-1).") unless Country[country]
end
更新
对于 Region 和 State,您可以像这样同时验证所有 3 个。
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
虽然 Region 似乎没有必要,因为您可以从国家/地区暗示这一点
before_validation {|record| record.region = Country[country].region if Country[country]}
【讨论】:
使用Wikipedia on ISO-3166-1 提供的数据创建一个夹具,并根据该数据验证国家/地区。
您还可以创建一个自动完成功能来简化输入。您可以查看自动完成provided here 以获得指导。
【讨论】: