Как я могу расширить область действия validates_uniqueness_of за пределы столбцов для данной модели? - PullRequest
0 голосов
/ 31 июля 2011

В стране много штатов, а в штате много городов. Я хочу убедиться, что никакие два города в одной стране не имеют одинакового названия.

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 голосов
/ 31 июля 2011

Лично я бы добавил country_id столбец к cities, хотя это явно избыточно. Я думаю, что иногда все в порядке, чтобы нормализовать винт и сохранить его быстрым и простым. Но это только я. validates_uniqueness_of кажется только принимает фактические столбцы таблицы в своей области видимости.

...