如何在给定模型的列之外扩展validates_uniqueness_of的范围?

时间:2011-07-31 12:23:44

标签: ruby-on-rails has-many-through nested-attributes

一个国家有很多州,一个州有很多城市。我想确保同一个国家的两个城市没有相同的名字。

class Country < ActiveRecord::Base
  has_many :states
  has_many :cities, :through => :states

  accepts_nested_attributes_for :states, :reject_if => lambda { |state| state[:name].blank?}, :allow_destroy => true

  validates_uniqueness_of :name
end

class State < ActiveRecord::Base
  belongs_to :country
  has_many :cities

  accepts_nested_attributes_for :cities, :reject_if => lambda { |city| city[:name].blank?}, :allow_destroy => true

  validates_presence_of :country
  validates_uniqueness_of :name, :scope => :country_id
end

class City < ActiveRecord::Base
  belongs_to :state
  has_one :country, :through => :state

  validates_presence_of :state
  validate :name_is_unique_in_country

  private
  def name_is_unique_in_country
    if City.joins(:state, :country).where(:cities => {:name => name}, :countries => {:id => State.find(state_id).country.id }).any?
      error.add("Two cities in the same Country can not have the same name")
    end
  end
end

有更简单的方法吗?我不是很喜欢'name_is_unique_in_country'。 加入有点混乱,我发现自己希望得到类似的东西:

:validates_uniqueness_of :name, :scope => country

但这是不可能的,因为有关该国的信息只能通过该州获得。

此外,当我使用嵌套属性同时创建州和城市时,我遇到了问题......

1 个答案:

答案 0 :(得分:0)

就个人而言,我会向country_id添加cities列,即使这显然是多余的。我认为有时可以通过简化规范化并保持快速和直接。但那只是我。 validates_uniqueness_of似乎只接受其范围内的实际表列。