2012-03-17 6 views
7

Я запускаю Ruby (1.9.3) на Rails (3.2.0) и имею проблему с проверкой виртуальных атрибутов.Проверка виртуальных атрибутов в Ruby on Rails

У меня есть модель Flight, которая представляет собой полет, который, помимо прочего, имеет атрибуты, которые представляют собой аэропорт вылета и прибытия.

Потому что select для выбора аэропорта потенциально огромный, я решил пойти на автозаполнение решения, которое работает отлично. Я использую before_validation обратный вызов, чтобы правильно заполнить фактический идентификатор аэропорта:

before_validation do 
    self.departure_airport = Airport.find_by_long_name(departure_airport_name) 
    self.arrival_airport = Airport.find_by_long_name(arrival_airport_name) 
end 

Проблемы, однако, что, когда пользователь вводит название аэропорта, который не существует в базе данных, фиксация терпит неудачу потому что идентификатор любого аэропорта - nil. Отлично. Что не велика, однако, заключается в том, что эта неудача проверки не отражается на форме, потому что технически, это вход для другого поля:

validates :departure_airport, :arrival_airport presence: true 

attr_accessor :departure_airport_name, :arrival_airport_name 

<%= f.input :departure_airport_name %> 
<%= f.input :arrival_airport_name %> 

Это даже способ правильно идти о, превращая название аэропорта в идентификатор в обратном вызове before_validation? И если да, то как я могу получить ошибки проверки для отображения атрибута виртуального имени аэропорта?

ответ

4

Я думаю, что вы идете правильным путем с обратным вызовом before_validation.

Вы можете проверить виртуальные атрибуты, как каждый нормальный атрибут. Таким образом, все, что вам нужно, это всего лишь некоторые валидации в модели. Попробуйте это:

validates :departure_airport, presence: true 
validates :arrival_airport, presence: true 

это должно добавить ошибку к ошибкам объектов и должны отображаться ошибка в вашей форме ...

+0

Спасибо за быстрый отклик! У меня уже есть проверки на 'departure_airport' и' arrival_airport'. Проблема в том, что это не поля, которые представляют «input» на форме. Я не могу просто проверить наличие, потому что, когда кто-то вводит в них текст, поле присутствует, но фактический объект «Аэропорт» будет отсутствовать. – Laurens

+0

Вот почему вы регистрируете обратный вызов 'before_validation'. Когда пользователь вводит тарабарщину, он не найдет аэропорт, и проверка не удастся. Ошибка будет добавлена ​​и отображена пользователю. Возможно, вам стоит подумать о добавлении настраиваемого массажа ошибок. – klump

+0

Извини, что я плохой. Я не понял. Возможно, вам нужен ваш собственный метод проверки. Вы можете добавлять ошибки к объекту с помощью 'self.errors.add (: fieldname," message ")'. Если теперь вы используете имя 'departure_airport_name' как имя поля и добавляете сообщение, оно будет отображаться в поле' departure_airport_name'. – klump

Смежные вопросы