I understand how this can be down when uploading directly to Cloudinary using the below syntax and passing the folder name as an argument.
Cloudinary::Uploader.upload("sample.jpg", :use_filename => true, :folder => "folder1/folder2")
However, I am using ActiveStorage, and when I upload a photo in the above manner it isn't attached to my Post
model or associated in any way with my app.
I am using the following code to attach images
post.send(:images).attach io: StringIO.new(new_data), filename: blob.filename.to_s,
content_type: 'image'
It does not accept an argument to specify the folder. I have tried my best to read both ActiveStorage and Cloudinary docs in an attempt to find a way to make this work, however, I cannot seem to figure it out.
I have seen that setting a custom folder header may be a way to get this to work, but again cannot figure out how to set a custom header for the above code which takes place in the below job
.
require 'tmpdir'
require 'fileutils'
require 'open-uri'
class ResizeImagesJob < ApplicationJob
queue_as :default
def perform(post)
post.images.each do |image|
blob = image.blob
blob.open do |temp_file|
path = temp_file.path
pipeline = ImageProcessing::MiniMagick.source(path)
.resize_to_limit(1200, 1200)
.call(destination: path)
new_data = File.binread(path)
post.send(:images).attach io: StringIO.new(new_data), filename: blob.filename.to_s,
content_type: 'image'
end
image.purge_later
end
end
end
What the above job is doing is waiting until after a post is created and then resizing and reattaching the photos to the post well deleting the originals. I am taking this approach to avoid integrity errors that take place resizing a post directly on Cloudinary after upload.
What I want to do is store the resized photos in a different folder. The reason for this is that I am using direct_upload
and it is possible for users to upload photos without ever creating a post. Thus causing me to store unused, photos. This would provide an easy way to identify and deal with such images.
You can dynamically set your folder on storage.yml:
cloudinary:
service: Cloudinary
folder: <%= Rails.env %>
And so Cloudinary will automatically create folders based on your Rails env:
This is a long due issue with Active Storage that seems to have been worked around by the Cloudinary team. Thanks for the amazing work ❤️