开发者

How can I expand the scope for validates_uniqueness_of, beyond columns for the given model?

开发者 https://www.devze.com 2023-03-25 09:26 出处:网络
A country has many states, and a state has many cities. I want to ensure that no two cities in the same country have the same name.

A country has many states, and a state has many cities. I want to ensure that no two cities in the same country have the same name.

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

Is there a simpler way? 开发者_JAVA技巧I'm not really liking 'name_is_unique_in_country'. The join is a bit messy, and I find myself wishing for something like:

:validates_uniqueness_of :name, :scope => country

But that's not possible as information about the country is only available through the state.

In addition, I'm running into problems when I use nested attributes to create a state and city at the same time...


Personally I would add a country_id column to cities, even though that's obviously redundant. I think sometimes it's ok to screw normalization and keep it speedy and straightforward. But that's just me. validates_uniqueness_of only seems to accept actual table columns in its scope.

0

精彩评论

暂无评论...
验证码 换一张
取 消