Seeding Carrierwave from external process - ruby-on-rails

In it's simplest form...
I'm using Carrierwave in an app to auto-upload images that exist on external sites so as to put as little load on them as possible. The first time I want to display an image I trigger Carrierwave to do the uploading.
The db is seeded with an image url written in a background Java process. Then in Ruby I assign the seed url to "remote_image_url" and save! to get the upload and versioning to happen. This all works fine.
However I have to store a field in the db that tells whether the upload has been triggered so that I don't trigger it every time the image is displayed. How can I tell if the "image" has been uploaded? The "image" field is actually an Uploader, is there a method that will tell me if it has been triggered?

Carrierwave downloads the remote file as soon as you assign it via model.remote_image_url=, and it moves the file to its final location (local storage, S3, etc) as soon as you call model.save. This happens synchronously, so if model.save has completed, and there hasn't been an error, your file has been stored.
To put it another way: If you just loaded a model from the database, and model.image? is true, then model.image.url should be a working URL.

Related

Remove unused files from ActiveStorage+DirectUpload

Consider the following example:
I have a form that includes a multiple files input;
The input file uses ActiveStorage and DirectUpload to upload files automatically as soon as they are included;
After adding some files they are uploaded automatically;
I never click the submit button so those files are never used nor accessible anywhere;
Does Rails support some built-in mechanism for removing these files or is something we have to implement ourselves?
Seems rather trivial to perform a DoS by continuously uploading files until something breaks.
Update 1
Forgot to mention that the example I'm following uses a 3rd party library (Dropzone in this case) and follow the example from the official documentation.
According to the documentation after a file upload we inject a hidden input field with the id of the uploaded blob.
I think the answer of Chiperific is good, since DirectUpload is executed in the submit there is little time for the requests to fail.
I mention requests because as far as i understand it, the process is like this:
The user selects a file from his computer and fills the rest form.
DirectUpload uploads the file to the storage.
The backend receives the body and updates the attachment and either creates or updates a model.
So, what happens if the file upload is successful but model validation is not? you would end up with a file in the storage without his corresponding model or with dirty one.
More information here: https://github.com/rails/rails/issues/31985
The answer then is no, rails does not have a mechanism of removing this files automatically. I guess you could check if the model creation/update was successful and remove the file manually if not.
I think your premise is incorrect.
The input file uses ActiveStorage and DirectUpload to upload files automatically as soon as they are included;
According to the docs:
Active Storage, with its included JavaScript library, supports uploading directly from the client to the cloud.
and
That's it! Uploads begin upon form submission.
So the point of Direct Storage seems to be to bypass some Rails ActiveStorage things and go straight to the service. BUT, it still doesn't happen until the form is submitted.
The example on the non-edge docs shows the user clicking "Submit" before the files are actually uploaded.

Should I delete uploaded files from the file system on my own?

I have a rails app where the user can upload files. The files get uploaded to an external cloud service by a backgroud jobs. It's vital for my app that the files won't get stored in the file system after they've been uploaded. Not right away, in general -- they must not remain in the file system.
Should I delete them on my own? Or will get deleted automatically?
Also, debugging my app, I noticied this for an attachment params:
[2] pry(#<MyController>)> my_params.tempfile.path
"/var/folders/qr/0v5z71xn7x503ykyv1j6lkp00000gn/T/RackMultipart20181007-10937-3ntmgg.png"
That file gets stored not in "/tmp" but in "/var" and that means that it won't get deleted automatically, right?
Note that I'm not using paperclip for this task.
You are right the files won't get deleted automatically.
You have to delete the file explicitly at some point in time.
It depends how you set it up. If you used Tempfile to save it then yes the files will be deleted when the object is garbage collected. If not then it probably won't be deleted.
If the files get stored on an external service it might be worth setting up ActiveStorage which allows you to directly upload to external storage providers without the file ever touching your server.

Rails upload excel file, validate and save

I am working on a rails engine that uploads a excel file, validates it and if there is no error than it will save it to database.
Now when ever a user mounts the engine and than go to the route provided by engine. He will have a form to upload the excel file. There are two buttons on page, i.e, upload and validate.
Once a user choose the file and when he click on upload i want that file only gets uploaded and don't get saved in db. Once i get the message the file is uploaded successfully, than i will validate the file. If it is a valid excel file with valid data than it will be saved into db. Now i am not getting how to go about it. I have seen this Railscasts video on uploading csv and excel file but here he is performing validation and save operation with import action but i want validation and save operation when user clicks on validate action. This Questions seems similar to my problem but i am not getting how do i access that uploaded file. I don't want that file to be saved in database. I mean when a user click on upload button that file gets only uploaded not saved. Than i will validate that file and save it's content to db.
This may seem very easy and simple questions for some experts but i am very new to rails and i am not sure how to go about it.
Someone please help me with a sample code, so that i can understand the workflow. Also note that both upload and validate actions are on same page. So when a file gets uploaded it needs to be stored somewhere temporarily, this is the first problem i am facing. I can do all the task if someone can tell me workflow with a sample code about uploading excel file. I am only having problem here that as both upload and validate action are on same page, so after upload request it needs to be on that page so that i can validate that file.
Any help would be appreciated, I am very beginner at rails and really confused here.
Two options:
Write code to upload the file and save to DB with a validated column set to false. Then the 'validate' button will locate the unvalidated file, validate it and set validated to true. You could have a periodic job deleting unvalidated files of a certain age. If you do this, use a helper gem like Paperclip.
Forego file upload frameworks and just manually save uploaded files to Tempfile.new 'spreadsheet'. This guide takes you through how to do that. Save that filename to session and use it to validate at a later point. When you're finally ready to persist to DB, again, consider using a helper gem.

Rails s3_direct_upload without file field

My website generates a file in javascript (audio recording) and I then want it to be uploaded to Amazon S3.
I first managed to get the uploading part working by sending the generated file to my server, where it is uploaded. However I would like now to upload the file directly to S3, without going through my server.
So I started to use the s3_direct_upload gem, which works great when using a file_field. However my file is generated by the javascript and :
- The value of a file field has to be set by the user for security reasons
- I do not want the user to have to interact with the upload
I tried to play with the S3Uploader class and to directly add data, without any success for now, it seems that I do not use the correct method.
Does anyone has any idea on how to achieve S3 direct upload without a file field ?
Thanks
Never mind, I found out that the S3Uploader class used by the s3_direct_upload gem has the same methods as the jQuery-File-Upload from which it is derived.
So one can call $("#s3_uploader").fileupload('send', {files: [f]});
And the f File will be uploaded to S3 directly

Tinymce rails image upload - how to delete images if post isn't created

Basically I fallowed this documentation: tinymce rails image upload
It works, but the problem is that It saves every image in the db before the actual post is created. Thus even if the post isn't finished or saved, the images still remain on the server. And that is just waisting space on the server.
Does anyone know a better way for image upload with tinymce ?

Resources