Вложенные формы, встроенные загрузки и индикаторы выполнения с Carrierwave в Rails - PullRequest
4 голосов
/ 19 августа 2011

У меня довольно эзотерический вариант использования для вложенных форм, загрузки нескольких файлов и индикаторов выполнения в Rails. Я не нашел никаких онлайн-дискуссий по этому поводу. Если я что-то упустил, извините. Пожалуйста, поправьте меня.

Вот что я хочу:

  1. Данная форма имеет несколько динамических полей. Одним из них является «прикрепить файл».
  2. Для этого «Прикрепить файл» мне нужен интерфейс, который по сути похож на gmail.
  3. Этот интерфейс позволяет вам:
    1. нажмите «прикрепить файл».
    2. выберите локальный файл, который сразу же начинает загружаться в фоновом режиме, и в это же время отображается индикатор выполнения.
    3. это позволяет вам написать ваше сообщение или добавить больше файлов.
    4. Вы можете отменить прямую загрузку и даже удалить вложения по факту, сняв флажок.

Вот модели и ассоциации, с которыми я работаю.

  1. У меня есть модель записи, в которой много аудиофайлов.
  2. Каждый аудиофайл содержит аудиоданные, а также метаданные, такие как размер, тип, дата создания и т. Д.
  3. Запись также имеет несколько других дочерних коллекций.

Вот как должна вести себя форма «Создать запись»:

  1. Это должно позволить пользователю добавлять несколько дочерних полей, включая несколько аудиофайлов.
  2. Пока что я использую превосходную вложенную форму (https://github.com/ryanb/nested_form) gem для создания дочерних записей записи, не относящихся к AudioFile. Это прекрасно работает.
  3. Мне нужно иметь возможность иметь похожие вложенные поля для загрузки нескольких аудиофайлов асинхронно, с индикаторами прогресса и возможностью отмены или удаления загруженных файлов.

Существует множество ресурсов, которые демонстрируют, как использовать загрузчики в сочетании с carrierwave для хранения файлов с информацией о прогрессе. Например, https://github.com/yortz/carrierwave_jquery_file_upload, и https://github.com/blueimp/jQuery-File-Upload/wiki/Rails-setup-for-V5.

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

Я не могу понять, как это сделать в контексте вложенной формы. Хитрые биты:

  1. Предположим, я записываю AJAX для создания поста из формы «Создать запись», и этот пост создает новую запись AudioFile. Как связать этот аудиофайл с еще не созданной записью?
  2. Если пользователь прерывает транзакцию, как будет очищена созданная таким образом запись AudioFile?

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

Спасибо, Apurva

1 Ответ

3 голосов
/ 20 ноября 2011

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

Подводя итог, можно сказать, что основная проблема заключалась в согласовании поведения CarrierWave, вложенных форм и точного контроля загрузки файлов.

Суть проблемы заключалась в том, что вложенные формы создают корневую запись и все ее ассоциации в одной операции POST с действием #create корневого контроллера.

В приведенном выше примере модель записи была корневой, в то время как AudioFile, Note и Категоризация были ассоциациями, которые должны быть созданы вместе с записью.

Таким образом, с помощью Nested Forms мне пришлось бы создавать все эти записи в одном POST, что исключало бы возможность отмены отдельных загрузок или параллельной загрузки с добавлением других полей (например, Notes).

Это не помогло бы улучшить пользовательский опыт.Мое решение было очень простым:

  1. Я решил не использовать вложенные формы.
  2. Запись # create будет всегда вызываться с пустыми параметрами.Атрибуты записи будут получать разумные значения по умолчанию в операции создания.
  3. Пользователь будет видеть только страницу редактирования # записи.
  4. На странице редактирования # записи у меня были независимые элементы управления для операций CRUD.на связанных моделях, которые будут маршрутизироваться на различные контроллеры через вызовы AJAX.Это работало, потому что каждая связанная модель имела действительный идентификатор записи для использования.
  5. Различные контроллеры возвращали бы фрагменты HTML, которые были бы записаны на главную страницу записи.

Это позволило встроенное редактирование всех полей на странице записи, даже если эти поля сопоставлены с различными (связанными) моделями.Таким образом, пользователь сможет загружать несколько файлов, добавлять заметки во время загрузки, воспроизводить уже загруженные файлы и отменять загрузки по желанию.

В результате весь пользовательский опыт стал намного более плавным.Это никогда не было бы достижимо с помощью вложенных форм по определению.

...