我有一张表User
create_table :users do |t|
t.string :first_name
t.string :last_name
t.string :country
t.string :region
t.string :city
t.timestamps
end
我需要验证国家和地区,还要检查区域是否属于国家/地区。 我使用gem countries进行国家验证。
#user.rb
class User < ActiveRecord::Base
validates_inclusion_of :country, in:Country.all.map(&:pop), :message => "wrong country format"
end
如何对区域&#39;进行验证?并检查区域是否属于国家
更新
使用@ engineersmnky的建议
#user.rb
validates :country, :region, presence: true
validate :location
def location
current_country = Country[country]
if current_country
errors.add(:region, "incorrect state for country #{current_country.name}.") unless current_country.map{ |k,v| v["name"]}.include?(region)
else
errors.add(:country, "must be a 2 character country representation (ISO 3166-1).")
end
end
在控制台中测试:
2.1.2 :001 > u = User.new(country:"US", region:"SomeState")
=> #<User id: nil, first_name: nil, last_name: nil, country: "US", region: "SomeRegion", city: nil, address: nil, zip: nil, phone: nil, company: nil, created_at: nil, updated_at: nil>
2.1.2 :002 > u.valid?
NoMethodError: undefined method `map' for #<Country:0x007fefb16dd140>
哪里出错?或者我理解错误:(
答案 0 :(得分:3)
已从我之前的帖子Here移出
虽然现在我按区域看到你的意思是状态
你也可以这样做
#optionally in:lambda{|user| Country[user.country].states.map{ |k,v| v["name"]}}
#for named states see below for further explanation
validate_inclusion_of :region, in:lambda{ |user| Country[user.country].states.keys}, if: lambda{ |user| Country[user.country]}
对于国家和地区/州,您可以像这样同时验证两者。
validates :country, :region, presence: true
validate :location_by_country
def location_by_country
current_country = Country[country]
if current_country
#this will work for short codes like "CA" or "01" etc.
#for named regions use:
# current_country.states.map{ |k,v| v["name"]}.include?(region)
#which would work for "California" Or "Lusaka"(it's in Zambia learn something new every day)
#for Either/Or use:
# current_country.states.map{|k,v| [k,v["name"]]}.flatten
#this will match "California" OR "CA"
errors.add(:region, "incorrect region for country #{current_country.name}.") unless current_country.states.keys.include?(region)
else
#optionally you could add an error here for :region as well
#since it can't find the country
errors.add(:country, "has wrong country format")
end
end