I have two services defined in the storage.yml
amazon:
service: S3
bucket: bucket1
region: eu-central-1
access_key_id: 321
secret_access_key: 321
unsafe_files:
service: S3
bucket: unsafe-files
region: eu-central-1
access_key_id: 123
secret_access_key: 123
I use the amazon service for some files and I wanted to use the unsafe_files
service for other files so that I can put the into another s3
bucket.
The models that use the unsafe_files
service look like that (very simple):
class Customer < ActiveRecord::Base
belongs_to :customer_image
end
class CustomerImage < Image
has_one_attached :file, service: Rails.configuration.settings[:unsafe_files_service]
end
Rails.configuration.settings[:unsafe_files_service]
is just unsafe_files
in rails application.rb
I'm setting
config.active_storage.service = :amazon
so that by default it uses the amazon
service defined in storage.yml
Now I want to direct upload the files using form_with
, it's also quite simple:
<%= form_with model: [@customer, CustomerImage.new] do |form| %>
<%=
form.file_field :file,
accept: 'image/jpeg',
direct_upload: true,
multipart: true
%>
<%= form.submit "submit" %>
<% end %>
now I know (or I think I know) how direct upload works under the hood in rails when using active_storage
.
Some javascript listens for the on form submit event and first takes what's in the file_field
and sends it to the DirectUploadsController
which checks the image, generates the direct upload url and then we directly upload the file to the specified service. It's all here: https://github.com/rails/rails/blob/6ecf1065da57360bdc9f1d85e2c2d9314dcb79e0/activestorage/app/controllers/active_storage/direct_uploads_controller.rb#L14
The service responds with the file key or id. Afterwards the form submission continues and we save the id that we have received and that's how the relationship between the file.
But when we hit the DirectUploadsController
and we create the blob it gets the default service_name (see: https://github.com/rails/rails/blob/6ecf1065da57360bdc9f1d85e2c2d9314dcb79e0/activestorage/app/models/active_storage/blob.rb#L115)
So long story short, when using direct upload I can't choose a service I have to rely on rails default service.
Is there a workaround for that? Or maybe I have missed something?
CodePudding user response:
If you want to call create_before_direct_upload!
yourself (so that you can specify the service_name) then I think you must override DirectUploadsController
somehow. You could write your own controller, or (advanced) try to re-open and patch DirectUploadsController
. My app does the former.
Update from the OP:
I ended up re-opening DirectUploadsController (and also adding an option to the form file_field to pass a custom direct_upload_url It works nicely although I don't like that I had to mingle with internals soo much. I've checked active_storage gem and it seems that one would have to just add this feature cause with current implementation there is no workaround. – beniutek