DEV Community

Cover image for Handling ActiveStorage direct uploads and server side form validations

Handling ActiveStorage direct uploads and server side form validations

Drew Bragg on October 31, 2018

Ok, so this is slightly hacky. Let me also preface this by saying there's probably no real need to do this if you add some client side form validat...
Collapse
 
nameisvijay profile image
Vijay Meena • Edited

Oh, Just upgraded to rails 6 today in order to check behavior. Things are changed in rails 6 (atleast for non direct-uploaded file). Now, uploaded file will only persist to storage if post gets saved successfully. Thus there won't be orphaned for records which won't be saved.

I still feel that server may not get chance to validate during direct-upload. I have yet to check behavior for direct-upload

Collapse
 
alispat profile image
Alisson Patrick

Hi guys! I believe I found a simpler solution for this issue on ActiveStorage.

Just put this hidden_field on your form:

<%= f.hidden_field :image, id: nil, value: params[:post][:image] rescue nil %>
Enter fullscreen mode Exit fullscreen mode

And there is no need to do any treatment on your controller.

Your form will end up like this:

<%= form_with(model: @post, local: trye) do |f| %>
  <%= f.text_field :title %>
  <%= f.text_area :body %>
  <%= f.hidden_field :image, id: nil, value: params[:post][:image] rescue nil %>
  <%= f.file_field :image, direct_upload: true %>
<% end %>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
bkspurgeon profile image
Ben Koshy

Thanks for the post. It's so simple -- after you know the solution!

Collapse
 
drbragg profile image
Drew Bragg

Glad you found it helpful! This is basically the post I wish I had been able to find. ๐Ÿ˜‚

Collapse
 
nameisvijay profile image
Vijay Meena • Edited

It won't stop creating orphaned file on cloud storage for some cases. For exmample, user has to upload their profile picture during registration to my website. If a user upload profile pic but doesn't submit form then it will still create orphaned file on storage.

I haven't used active storage yet but I used javascript and aws-sdk to direct-upload files few months back on rails4 app. I faced same problem and implemented same hack as you suggested. But, I modified design a bit. I created two buckets on my amazon s3 storage. First "cache" and second "production". My app direct-uploaded all the stuff to "cache" bucket and then my model checked required validation at form-submission and used before_save filter which copied image from "cache" bucket to "production" bucket using aws-sdk if validation succeeded.

I also set expiry time limit to "cache" file so all these temporary files were auto-purged. This way, all orphaned uploads were only saved to "cache" and actual records were saved to "production" and "cache" was auto-purged in 24 hours by s3.

I don't know if it can work with active-storage (because i heard that we can only use single bucket with active-storage) I also don't know if what i did was a proper way to do it but it worked for me.

Collapse
 
bkspurgeon profile image
Ben Koshy

This is the exact method employed by the Shrine gem - which is a masterpiece IMO. Takes away all the headaches of validations with the "cache" and "storage" sequestrations. However if you are using ActionText, and want the equivalent functionality using Shrine - then it looks like you're out of luck if you want something out of the box.

Collapse
 
medboo profile image
medboo

other simple ways are:

  • Put image upload on its own (in a separate step), after the user fills up the form, he could direct upload the image in the next step.

  • You can make a popup that lists all user uploads, so users can upload images and the popup will be the source of choosing images, that also help in the future if the user wants to use the same images.

  • in case you insist to use the way you describe in your post, you can make a cron job that delete orphaned files after x time from their creation

sometimes you just need to find another way to think about it!

Collapse
 
amarafinbarrs profile image
Amara Finbarrs

Please can someone help me, I have tried but I can't seem to make the code work. The image form still clears if my form fails a validation check?