Nested forms, embedded downloads, and progress bars with Carrierwave in Rails

I have a pretty esoteric utility for nested forms, multi-file downloads, and progress indicators in Rails. I have not found any online discussions about this yet. If I missed something, I'm really sorry. Please correct me.

Here is what I want:

  • This form has several dynamic fields. One of them is Attach File.
  • For this "Attach file" I need an interface that is essentially similar to gmail.
  • This interface allows you to:
    • Click Attach File.
    • select a local file that will start downloading immediately in the background, and at the same time, a progress bar will be displayed.
    • This allows you to write your message or add additional files.
    • You can cancel the live download and even delete attachments after the fact by unchecking the box.

Here are the models and associations I work with.

  • I have a recording model in which there are a lot of audio files.
  • Each AudioFile contains audio data as well as metadata such as size, type, date, etc.
  • The record also has several other child collections.

Here's what the Create Record form should look like:

  • It should allow the user to add several child fields, including several audio files.
  • So far, I have been using the gorgeous nesting pearl (https://github.com/ryanb/nested_form) to create non-AudioFile children. IT works brilliantly.
  • I want to have similar nested fields for downloading multiple audio files, asynchronously, with progress indicators and with the ability to cancel or delete downloaded files.

There are many resources that demonstrate how to use bootloaders in conjunction with a carrier to store progress information files. For example, https://github.com/yortz/carrierwave_jquery_file_upload and https://github.com/blueimp/jQuery-File-Upload/wiki/Rails-setup-for-V5 .

In essence, what these examples do is generate a request from one of these loaders, which aims to create a controller for the model to which the carrier loader is attached. I have everything to work fine.

I cannot figure out how to do this in the context of a nested form. Complex bits:

  • Suppose I write AJAX to record from the Create Record form, and create a new AudioFile record. How to associate this audio file with a record that has not yet been created?
  • If the user aborts the transaction, how will the AudioFile created in this way be cleared?

I can think of hacker ways to do both of the above, but I wonder if there are more elegant approaches. I am new to rails, so I assume that I am not using it fully.

Thanks Apurva

+4
source share
1 answer

I thought I would contribute to the community by sharing how I solved this problem.

To summarize, the main problem was to reconcile the behavior of CarrierWave, nested forms and fine-grained control over file downloads.

The essence of the problem was that the nested forms create the root entry and all its associations in one POST operation for the #create action of the root controller.

In the above example, the recording model was the root, while AudioFile, Note, and Categorization were the associations created with the recording.

Thus, with nested forms, I would have to create all these entries in one POST, which would exclude the possibility of canceling the download separately or loading in parallel with the addition of other fields (for example, Notes).

This would not affect a good user interface. My solution was very simple:

  • I decided not to use nested forms.
  • The entry # create will always invoke with empty parameters. Record attributes will receive reasonable defaults in the create operation.
  • The user will see the edit page of the entry No.
  • On the entry edit page #, I had independent controls for CRUD operations on related models that would be routed to different controllers via AJAX calls. This worked because each associated model had a valid id_file to use.
  • Various controllers will return HTML fragments that will be written to the main page of the recording.

This included inline editing of all the fields on the Record page, although these fields were mapped to different (related) models. Thus, the user will be able to upload multiple files, add notes while they are being downloaded, play already downloaded files, and cancel downloading as desired.

As a result, the entire user interface was much smoother. This would not be possible with nested forms by definition.

+4
source

All Articles