Проверка уникальности атрибута в двух таблицах / моделях

В моем приложении Rails есть два разных типа пользовательских (разрабатываемых) моделей. Врач и пациент. Это моя вина, что я не определил пользователя высшего класса и не унаследовал от него атрибуты. У них есть общий атрибут - личный идентификационный номер, и я хочу, чтобы два раза проверяли уникальность этого атрибута в обеих таблицах. Я немного искал и увидел этот ответ.

Я применил все, как там написано, но это не повлияло.

#patient.rb 
class Patient < ActiveRecord::Base

...
  validates_uniqueness_of :pin 
  validate :pin_not_on_doctors

  private

    def pin_not_on_doctors
        Doctor.where(:pin => self.pin).first.nil?
    end
end
#doctor.rb
class Doctor < ActiveRecord::Base

...
  validates_uniqueness_of :pin 
  validate :pin_not_on_patients

  private

    def pin_not_on_patients
        Patient.where(:pin => self.pin).first.nil?
    end
end

Сначала я создал экземпляр пациента, затем экземпляр врача с той же булавкой, которую я использовал в моем первом (пациенте) случае. Rails неожиданно не выдал сообщение об ошибке и не создал экземпляр Doctor, и, что более интересно, devise также закрыл глаза на дублирующиеся электронные письма.

Как я могу решить эту проблему?


person marmeladze    schedule 23.04.2015    source источник


Ответы (2)


Вы должны добавить ошибку в функцию проверки: http://api.rubyonrails.org/classes/ActiveModel/Errors.html

def pin_not_on_doctors
    errors.add :pin, "already exists" if Doctor.exists?(:pin => self.pin)
end
person Shalev Shalit    schedule 23.04.2015
comment
Приятель, извините за недоразумение, моя проблема на самом деле не в сообщениях об ошибках, а в том, как меня обрабатывают рельсы :) Я ожидал, что он не создаст экземпляр Doctor из-за дублирующегося контакта. Но это создало. Я сейчас обновлю соответствующую часть. P.S. В любом случае, я проверил ваш код, и результат такой же. Может проблема в другом. P.P.S. В любом случае спасибо за внимание :) - person marmeladze; 23.04.2015
comment
см. комментарий к вашему ответу, вы должны добавить ошибку. - person Shalev Shalit; 24.04.2015

Помимо добавления ошибки, попробуйте добавить строку для возврата true / false,

Что-то вроде,

def pin_not_on_doctors
    errors.add :pin, "already exits" if Doctor.exists?(:pin => self.pin)
    Doctor.exists?(:pin => self.pin)
end

Я не знаю деталей вашего приложения, но в зависимости от того, как вы на самом деле создаете объект в этом случае, это может понадобиться.

РЕДАКТИРОВАТЬ: неправильно прочитал что-то в оригинале, похоже, ваша текущая версия просто возвращает true / false, поэтому это, вероятно, не поможет. Извините.

person Mangesh Tamhankar    schedule 23.04.2015