2016-11-13 2 views
2

Рассмотрим модель пользователя со следующими полями:Многоступенчатая проверка модели ActiveRecord в

  • Имя (обязательно)
  • Фамилия (обязательно)
  • E-mail (обязательно)
  • Пароль (обязательно)
  • Телефон (обязательно, размер: 10 цифр)
  • Адрес (обязательно)

И регистрационная форма многоступенчатым со следующими шагами:

  • первый шаг с полями Имя, Фамилия и Email
  • второго шага с паролем, телефон и адрес.

Как бы вы создали решение для проверки ввода на каждом шагу?

Стандартный способ ActiveRecord не работает, поскольку он проверяет все поля одновременно.

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

+1

Лямбда условная, основанная на атрибуте 'step'? Конечно, у вас может получиться сложный код контроллера. 'validates: first_name, наличие: true, if: lambda {| user | user.step === 1} '. Если вы найдете хороший ответ, сообщество Rails с удовольствием узнает :) –

+0

Вам нужно иметь экземпляр 'User' до конца? Вы могли бы построить одну или две временные модели, отличные от '' User', а затем преобразовать их в реальный 'User', когда вы закончите.Та же логика в целом, но условность валидации будет обрабатываться путем разделения моделей, а не сложной сложностью в «User». –

ответ

2

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

Теперь это, вероятно, не самый элегантный способ сделать это, но он эффективен и не загромождает код слишком много.

Добавить атрибут переходного процесса step в модель.

attr_accessor :step 

Добавьте следующий метод в модели, чтобы проверить, на правильном шаге:

def on_step(step_number) 
    step == step_number or step.nil? 
end 

Причина step.nil? - это имеет то преимущество, что если вы хотите использовать проверку на этой модели без использования шагов просто не присваивайте значение для шага на вашей модели, и метод позволит возвращать true, позволяя всегда выполнять валидацию.

Изменить валидацию обрабатывать только если на правом шаге или обойти, если не используя шаги

validates :first_name, if: "on_step 1", presence: true 
validates :last_name, if: "on_step 1", presence:true 
validates :email,  if: "on_step 1", presence:true 

validates :password, if: "on_step 2", presence:true 
validates :phone,  if: "on_step 2", format:{ with: TEL_REGEX }, allow_blank: false 
validates :address, if: "on_step 2", presence:true 

Конечно, не забудьте установить текущий шаг для модели, например, путем жесткого кодирования его в скрытое поле формы (при рендеринге отдельных форм для каждого шага) и изменение ваших параметров для его получения.