Валидация формы, как сохранить загруженные файлы?
Делать отдельный файловый менеджер для загрузки не подходит - можно загрузить лишние файлы, появляются трудности в редактировании/обновлении записей. AJAX валидация формы решит проблему частично - если один из файлов не пройдет, то придется загружать все файлы заново.
У вас как раз накопился технический долг в виде реализации полноценного файлового менеджера.
Который должен сразу после выбора пользователем файлов отправлять каждый файл по ajax на сервер. Сервер в это время складывает файлы во временный каталог пользователя, отдавая в качестве ajax-ответа его временное хэш-имя. Во время отправки формы вы уже не отправляете содержимое input[type=file], а отправляете список хэш-имен удачно загруженных файлов, а на стороне сервера если все поля валидны и файлы валидны (их можно допроверить), то просто копируете файлы из временного каталога в постоянный (или в базу, или в облако, или другой каталог облака, смотря где основное хранилище). Если какая-та проверка неудачная, то вы легко можете вернуть обратно клиенту его заполненные поля, и список загруженных файлов, указав, в каком файле какая ошибка. На стороне клиента можно восстановить как поля, так и список файлов в менеджере.
Если не хотите в полной мере решать технический долг, то можно поступить более простым путем.
После выбора файлов пользователем, вычитываете их содержимое объектом FileReader и складываете в кодировке base64 в скрытые поля input[type=hidden] (при окончании зачищаете input[type=file], чтобы форма была нагружена только бинарными данными из скрытых полей), это позволит вам отправлять список файлов вместе с отправкой формы и восстанавливать input[type=hidden] поля при возникновении ошибки, при возврате данных формы обратно клиенту для корректировки.
Такой подход увеличит время отправки и получения формы, не освободит от того, что вам нужно прорисовывать состояние списка файлов на форме, освободит только от использования ajax.
загрузка и проверка файлов плохо вписывается в абстрактную модель, поэтому модель обычно содержит только самые общие проверки - передан ли файл и его тип, а непосредственная загрузка и фильтрация файла выполняется в отдельном контроллере/хэлпере. Из-за ограничений по размеру и кол-ву файлов на виртуалках все массовые решения грузят файлы по одному - вначале проряются данные и наличие файлов и создается запись в базе, а уже потом по ее idшнику догружаются файлы.