Processing file before upload using ActiveStorage - ruby-on-rails

How would I process a file before it's uploaded using activestorage. I need to be able to modify an svg file's content before it actually gets uploaded to S3. Can't seem to find any callbacks.

There is no way to do this natively with ActiveStorage. It's the major drawback with using ActiveStorage.
As far as I know, the only way to modify an upload is to create a variant of the original upload after it is created...which creates a (completely different) variant image based on the image that was originally uploaded.
ActiveStorage is easy to setup but, after using it with a few applications, Carrierwave..etc seem like better options.
In addition, if you want to upload in a background job, ActiveStorage is a pain.

Related

Upload system-generated file to S3 using ActiveStorage?

I have a need to upload a system-generated file to S3. I'm aware that I could use something like the AWS Ruby SDK for this. However, I'm already using ActiveStorage elsewhere in my application and it seems simpler, if possible, to use ActiveStorage for everything rather than ActiveStorage plus some other library.
Is this possible using ActiveStorage?
I was able to find the answer in this part of the documentation:
#message.image.attach(io: File.open('/path/to/file'), filename: 'file.pdf')

Prawn PDF: how to add images uploaded with dragonfly

I like to generate PDF-Files which also includes images uploaded by the user. The prawn gem works so far, and can also embed images located in the file system.
My problem is that I want to include user uploaded images, and where these images are stored will probably change in the future (from file system to some cloud service).
I use the dragonfly gem for handling the images, this uses rack to access the images and sometimes process them on the fly.
Now the simpliest idea does not work
(with report being my object and spot_image my image field)
image report.spot_image
no implicit conversion of #<Class:0x007fc07ecf1110> into String
I tried also to open the file via http with open-uri. This should work, but it blocks on my development machine, I think because the development rails server is single threaded:
image_path = report.spot_image.remote_url
image_url = "#{view.request.protocol}\#view.request.host_with_port}
/#{image_path.sub(/^\//,"")}"
image open(image_url) # timeout in development-mode
It may probably work in production, but even then it does a needless http-request. Can I ask dragonfly (or rack) directly for the image? prawn uses duck-typing and needs some object that responds to read and rewind as image.
I found relevant documentation about dragonfly file handling. The following did not work:
The report.spot_image.data method returns the image data as string, but prawn recognizes the data as path instead of as image data. The dragonfly tempfile method returns a closed temporary file, but prawn does not recognize that it can open it.
I had success with the file method, which returns an open file handle. It is unclear if prawn is closing this file than. So I used the block-style method to make sure the file is closed:
report.spot_image.file do |f|
image f
end
This works so far. (not yet tested with cloud storage)

Local file upload: File.open or StringIO

My application allows a user to upload an image and then create different versions of that image (e.g. aligned and cropped with another image). The intermediate step is that I need to copy the uploaded file to another object and process it. The easiest way to do this is to upload it locally.
From the carrierwave wiki, they suggest using a modified version of StringIO.
On the carreirwave readme, they also suggest using File.open (something like obj.image=File.open('path_to_file').
I've also found references to using fixture_file_upload from ActionDispatch::TestProcess (usually in testing, but I'm unsure why it is restricted to that environment).
Can anyone give me a good explanation on the pros and cons (if any) of using these methods?
Thanks.
I just discovered one major difference, at least in the context of carrierwave. If you use carrierwave with the move_to_cache option set to true and mount your upload column with File.open, the file given to File.open will be moved, while with StringIO, it won't.

carrierwave upload caching

How does carrierwave upload caching functionality work? From what I've read, it looks like it keeps the uploaded file in public/uploads/tmp to avoid reupload across form redisplays. I am guessing the cache would get assigned a unique id, but still be publicly accessible. How to make it more secure for sensitive uploads or disable this feature altogether?
One way to avoid this is to have the uploader as a separate model from the target model, such that validation errors won't require reuploading.
CarrierWave keeps uploaded images in a cache dir so you can easily re-submit forms in case of validation errors without forcing your users to re-upload images.
The cache dir in default is public/uploads/tmp but you can change it by setting the cache_dir configuration parameter.
Usually uploaded images are available for download without authentication. Therefore, placing uploaded and cached files in a public directory is fine. You can also change your uploader class to have a filename method that generates a unique random ID to make it less guessable.
By the way, this blog post describes how to integrate CarrierWave while storing and transforming images in the cloud and delivering through a CDN.

Which plugins/gems should I use to dynamically generate thumbnails on-the-fly in Rails 3?

So, the thing is. I'm building my first rails app which reads images from a directory and it's subdirs. Now, I want to generate dynamic thumbnails of those images. But I don't want to fill up that directory with the thumbnail images. I was thinking of caching these thumbs separately for each user in temporary directory.
Oh, and, I would also need the dimensions of the images for some css magic.
What plugins/gems/... should I use to accomplish this?
You should rmagick coupled with Paperclip. In this way you can specify the dimensions (and many other attributes of the images), and make thumbnails on the fly.
On top of this, I would also add in delayed_job which will background the process of the images so if any of them are provided by the client, they won't have to wait for it to complete client-side.
rMagick : http://github.com/rmagick/rmagick
Paperclip: http://github.com/thoughtbot/paperclip
delayed_job: http://github.com/collectiveidea/delayed_job

Resources