loading...
Народ, я тут себя идиотом ощущаю.
Рассмотрим простую ситуацию: отправка веб-формы с валидацией. Предположим, url, отвечающий за форму, будет /user/create.
Как делаю я:
GET /user/create – отображение формы
POST /user/create – обработка данных и
– либо сохранение данных + редирект на /user/detail/%id%
– либо вывод формы обратно вместе с ошибками валидации
Как делают люди (паттерн PRG):
GET /user/create – отображение формы
POST /user – обработка данных и
– либо сохранение данных + редирект на /user/detail/%id%
– либо сохранение ошибок в сессию + редирект на /user/create + добавление ошибок из сессии к форме
Допустим, на конкретные урлы посрать, restful, там, вот это всё.
Но в паттерне PRG присутствует два неловких момента:
1. лишний запрос (из-за редиректа)
2. протаскивание ошибок через сессию
Профит же (достаточно сомнительный, на мой взгляд) в том, что пользователь, случайно нажав F5, не получит срашное окно “подтвердите повторную отправку формы”.
Поговорим об этом?
PRG,
присоединюсь к вопросу. тоже хочется придумать как это правильно организовать такую вещь
Всегда делал первым (твоим) способом и не переживал на этот счёт.
Кроме того, момент с протаскиванием в сессии ошибок действительно крайне неловкий. После каждого рендера формы я должен очищать в сессии эти ошибки? Если нет – то после какой-либо навигации по сайту и вернувшись снова к форме, я увижу форму с ошибками и уже введенными данными. Понятно, что в некоторых ситуациях это приятный behaviour – но я думаю такие моменты нужно реализовывать специально, а не как сопутствующий функционал.
Так же довольно странным каж-ся кол-во действий, которое необходимо совершить для сираной валидации и вывода сообщений об ошибках. Допустим, у меня несколько бэкендов и сессию я положил куда-нибудь в redis… На каждый submit 1-2 доп. запроса в редис – довольно пугающе.
Посмотри на форм-фреймворк симфони и прекрати уже пытаться изобрести велосипед, который до тебя умные люди миллион раз изобрели.
опиши в двух словах плз.
Потому что, к примеру, в Yii обработка форм идет по первому методу, в Laravel (где много чего из Симфони утащили) – по второму.
Переотправка формы по F5 – это провал для программиста. Хранить флэши в сессии – это оок. Юзай PRG.
новый объект – /obj/new / редактирование /obj/edit/id/1
сабмит на /obj/create
если валидно – /obj/show/id/1
Если невалидно – остаёмся на /obj/create
Схема такая. Форма создаётся два раза – на new/edit и на create, только во втором случае на неё биндится реквест и она перестаёт быть пустой. Следовательно, валидация вся проходит на /create/
Флеши нужно ставить только вроде “Спасибо, вы успешно сохранили объект”
речь не только о флешах, но и о пробросе пользовательских данных.
В первом случае засабмиченные данные рендерятся прямо в форму (если валидатор не пропустил).
Во втором – сохраняются в сессию, происходит редирект, извлекаются из сессии, рендерятся в форму (иначе форма будет пустая).
Это ок?
ну, похоже на то, как я обычно делаю, да. Только не очень понятен смысл существования двух урлов /new и /create. Один фиг, при невалидной форме на create остаемся.
оок. Это тот же флеш. Сериализовал модель, сунул в сессию, редиректнул, десериализовал. Или можно в базу класть, в шаредмем, да хоть куда.
нашёл кого слушать
new – это просто пустая форма, без какой бы то ни было модели. Create – процессинг модели. При этом create принимает только POST
в чем проблема сохранять инфу об ошибки в сессии в первом случае?
Зацени как всё просто в Yii:
/www/protected/controllers/UserControlle r.php:
class UserController extends Controller {
public function actionCreate() {
$model = new User(‘create’);
if(isset($_POST[‘User’])) {
$model->attributes = $_POST[‘User’];
if($model->validate() && $model->save()) {
$this->redirect(‘view’,array(‘id’=>$model->id));
} else {
// Это пример как ошибки в сессии сохранить, но в Yii необязательно
app()->user->setFlash(‘error’, CHtml::errorSummary($model));
}
}
$this->render(‘view’,array(
‘model’=>$model,
));
}
public function actionView($id) {
$this->render(‘view’,array(
‘model’=>$this->findModel(‘User’, $id),
));
}
}
пиздец ебаный.
бро, как в Yii – я знаю 🙂
Речь не о конкретной реализации, а о подходе:
вывод сразу + мерзкий confirm form resubmit VS протаскивание через хранилище + мерзкий лишний редирект.
в редиректе ничего плохого нет, а в ресабмите – есть. Это и конфуз пользователя и ошибочная отсылка данных со всеми вытекающими. Веб у нас стейтлесс, пусть таковым и остается.
Кстати, стоит добавить что перенос формы на XHR позволит убрать назойливое окно ресабмита, а при этом так же избавит от повторного рендеринга страницы с формой. Большая часть современных фрейморков позволяют без особых проблем реализовать ajax-отправку + валидацию формы с результатом валидации в виде, например, json-а. В случае возврата success, делать редирект на client-side с предварительным выводом сообщения об успешном выполнения операции и, например, loading bar-а.
Да, при всем этом можно оставить обратную совместимость с первым вариантом, если вдруг не работает Ajax o_o
В этом случае и оптимальная по нагрузке реализация, к тому же лишенная недостатков обоих случаев.
да, я вот тоже не очень понял, почему бы не использовать ajax.
это – лучший вариант, если делать по уму.