Pull to refresh

Comments 17

На мой взгляд контроль целостности данных это все-таки задача модели. В приведенных вами примерах, речь идет все го лишь о разных типах пользователей, и конкретная валидация будет просто зависеть от типа конкретного пользователя. Если это обычный пользователь, то проверяем чтоб у него был пароль и email, если это twitter-пользователь, то проверяем чтоб у него был oauth ключи от твиттера.

В случае мобильного приложения в котором не нужно проверять email пользователя, мы именно в реализации API передает модели что-то типа email_confirmed => true, потому что тут как бы API говорит о том что с email этого пользователя все ок и его не нужно дополнительно проверять.
Целостность данных != валидация формы.

Форм может быть много, и валидация в них может быть разная.
Думаю, здесь путаются понятия валидации, как целостности данных, и валидации, как корректности ввода.
И если целостность данных должна относиться к уровню модели, то корректность ввода — это уровень представления… или в крайнем случае — контроллер, поскольку view-уровень в рельсах тупой. Но по MVC он и должен быть тупым. А потому, IMHO, тут стоит говорить не о косяках модельной валидации, а о недостаточности MVC. То есть просится или «презентер» или ViewModel.
У нас это решилось просто. Мы отказались от рельсовского View-уровня, ограничив рельсы выдачей json, а все остальное — на backbone.js При этом бекбоновские вьюшки как занимают соответствующий слой, валидируя корректность ввода.
А как же защита от атак? Все, что проверяется на клиенте, надо проверять и на сервере, как минимум.
Не все!
Только то, что связано с целостностью данных. Проверка того, что пользователь ввел именно то, что хотел ввести (например — повтор пароля), это задача уровня представления.
в первую очередь на сервере… плохая тенденция концентрироваться на клиенте
Всегда так делал:

# user.rb

validate :email,
  presence: true,
  email: true
  unless: :skip_email_validation?

validate :password,
  confirmation: true,
  unless: :skip_password_confirmation?

def skip_password_confirmation?
  persisted? and !password_changed?
end

def skip_email_validation?
  twitter_account? # просто пример, но логика, думаю, ясна
end


А дальше уже рулить всем этим по вкусу. Контроль целостности — задача модели. Модель должна быть валидироваться вне зависимости от контекста. Буть то юзер-из-твиттера или обычный.
всегда можно сделать виртуальный аттрибут registration_type, например, а в методе skip_email_validation? проверять пропускать ли валидацию мыла или нет. В контроллере же, не забывать подставить этот самый атрибут, или даже в роутере.
Что то странное по ссылке yii, стандартно у него есть сценарии, которые можно указывать в зависимости от текущей ситуации, благодаря этому применяются нужные правила валидации, в соответствии с выбранным сценарием.
Rails поддерживает «Single table inheritance» (не знаю как можно перевести на русский). Вполне можно создать 2 модели для одной табилицы и обрабатывать подобные ситуации именно так.
Наследование, формируемое с помощью одной таблицы.
UFO landed and left these words here
Они были жуткими, громоздкими и совершенно не очевидными. Всех возможностей форм можно добиться и без подобных аналогов.
UFO landed and left these words here
Zend_Form все же с моделями не связан никак — с легкостью реализовывал описанные в статье «проблемы» валиадации без всякого напряга. Так что «not affected».
Only those users with full accounts are able to leave comments. Log in, please.