【问题标题】:Rails 4. Country and Region/State validation in modelRails 4. 模型中的国家和地区/州验证
【发布时间】:2014-07-31 17:33:50
【问题描述】:

我有一张桌子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

如何对“地区”使用验证并检查地区是否属于国家/地区

更新

使用@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>

哪里出错了?或者我理解错了:(

【问题讨论】:

  • 它应该是current_country.states.map{ |k,v| v["name"]}.include?(region) 你错过了states Hash

标签: ruby-on-rails validation ruby-on-rails-4 model


【解决方案1】:

移自我之前的帖子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

【讨论】:

  • 我收到错误undefined method map' `。请看问题更新
  • @Derk153 它应该是 current_country.states.map{ |k,v| v["name"]}.include?(region) 你错过了 states Hash
  • 非常感谢!很好的答案,很好的解决方案。我爱你,伙计,你太棒了!
  • @Derk153 没问题,很高兴它起作用了。更重要的是,我希望您在此过程中学到了一些东西。
  • 区域是正确的术语。州是一种地区。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多