Skip to content

Dynamic attachment uploads do not work with cloud storage services #9360

@ahukkanen

Description

@ahukkanen

Describe the bug
As it was reported by @oriolgual, the attachment uploads are broken after #8681 when using a cloud storage service, such as Amazon S3, Azure Blobs, GCS, etc.

To Reproduce
Steps to reproduce the behavior:

  1. Configure the site to use a remote storage service (S3, GCS or AzureStorage)
  2. Go to the voting space
  3. Try to uploaded a census data CSV (also works for other places where you have to upload a CSV)
  4. See error (stacktrace below)

Expected behavior
I would expect the CSV uploads to work also when using remote storage engines.

Screenshots
N/A

Stacktrace

NoMethodError (undefined method `path_for' for #<ActiveStorage::Service::S3Service:0x000055fbb8327ad0 @client=#<Aws::S3::Resource:0x000055fbb8327850 @client=#<Aws::S3::Client>>, @bucket=#<Aws::S3::Bucket:0x000055fbb8595448 @name="decidim-staging", @data=nil, @client=#<Aws::S3::Client>, @waiter_block_warned=false, @resolved_region="eu-central-1", @arn=nil>, @multipart_upload_threshold=104857600, @public=false, @upload_options={}, @name=:amazon>):
decidim (b5eedf63462a) decidim-elections/app/commands/decidim/votings/census/admin/create_dataset.rb:88:in `file_path'
decidim (b5eedf63462a) decidim-elections/app/commands/decidim/votings/census/admin/create_dataset.rb:84:in `file_lines_count'
decidim (b5eedf63462a) decidim-elections/app/commands/decidim/votings/census/admin/create_dataset.rb:80:in `csv_row_count'
decidim (b5eedf63462a) decidim-elections/app/commands/decidim/votings/census/admin/create_dataset.rb:52:in `create_census_dataset!'
decidim (b5eedf63462a) decidim-elections/app/commands/decidim/votings/census/admin/create_dataset.rb:26:in `call'
decidim (b5eedf63462a) decidim-core/lib/decidim/command.rb:18:in `call'
decidim (b5eedf63462a) decidim-elections/app/controllers/decidim/votings/census/admin/census_controller.rb:28:in `create'
actionpack (6.1.6) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (6.1.6) lib/abstract_controller/base.rb:228:in `process_action'
actionpack (6.1.6) lib/action_controller/metal/rendering.rb:30:in `process_action'

Extra data (please complete the following information):

  • Device: (any)
  • Device OS: (any)
  • Browser: (any)
  • Decidim Version: develop
  • Decidim installation: staging

Additional context
The reason for the bug is that the local disk service implements the path_for method that we are using:
https://github.com/rails/rails/blob/06b1000f44694627a7245a8a3447551f9231cf7a/activestorage/lib/active_storage/service/disk_service.rb#L99-L101

But e.g. Amazon S3 adapter does not implement (look for path_for in the class):
https://github.com/rails/rails/blob/06b1000f44694627a7245a8a3447551f9231cf7a/activestorage/lib/active_storage/service/s3_service.rb

Why this is that when using the cloud storage services, the files do not live locally on the user's machine but in the cloud storage service remotely.

E.g. the ratonvirus gem handles this by creating a local tempfile which you can refer using a path:
https://github.com/mainio/ratonvirus/blob/d0e4371895cf074266f91a06dd06f597f0d42e8e/lib/ratonvirus/storage/support/io_handling.rb#L15-L38

All storage service provide the download method which we could use to download the file and create a tempfile out of it while we need to read it locally.

There are multiple places where we refer to path_for which need to be fixed. Search with service.path_for from the codebase.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions