Question

Rails ActiveStorage / Retrieve file from Space

We have a rails application that stores images with ActiveStorage and each image is uploaded to IPFS using Pinata. For staging/production we have decided to test Digital Ocean’s Space.

The image is being uploaded correctly to Space.

The storage.yml

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>
  
digitalocean:
  service: "s3"
  endpoint: "https://nyc3.digitaloceanspaces.com/"
  access_key_id: <%= Rails.application.credentials.dig(:digitalocean, :access_key) %>
  secret_access_key: <%= Rails.application.credentials.dig(:digitalocean, :secret) %>
  bucket: "stg-vikuimages"
  region: "nyc3"

We are using the following code to Pin the image to IPFS

    def upload(collection)
      attachment = collection.attachment
      file_path = ActiveStorage::Blob.service.send(:path_for, attachment.key)
      content_type = attachment.blob.content_type
      file_io = Faraday::UploadIO.new(file_path, content_type)
      ok, image_ipfs_hash = send_file(file_io)
      return unless ok
      metadata = {
        name: collection.name,
        description: collection.description,
        image: 'https://ipfs.io/ipfs/' + image_ipfs_hash
      }
      File.write("tmp/metadata.json", metadata.to_json)
      metadata_io = Faraday::UploadIO.new("tmp/metadata.json", 'application/json')
      ok, metadata_ipfs_hash = send_file(metadata_io)
      collection.update(image_hash: image_ipfs_hash, metadata_hash: metadata_ipfs_hash)
      ok ? metadata_ipfs_hash : nil
    end

I am getting the following error. Since when using the “S3” service it tells me that the aws sdk does not contain “path_for” function.

ERROR: undefined method `path_for' for #<ActiveStorage::Service::S3Service:0x0000564f7e2d29f8>

I tried to retrieve the image from the space modifying the code as follows

    def upload(collection)
      # New Line
      s3 = Aws::S3::Client.new
      resp = s3.get_object(bucket: 'stg-vikuimages', key: attachment.key)
      hola = resp.body
      # End New Line
      attachment = collection.attachment
      file_path = ActiveStorage::Blob.service.send(:path_for, attachment.key)
      content_type = attachment.blob.content_type
      file_io = Faraday::UploadIO.new(file_path, content_type)
      ok, image_ipfs_hash = send_file(file_io)
      return unless ok
      metadata = {
        name: collection.name,
        description: collection.description,
        image: 'https://ipfs.io/ipfs/' + image_ipfs_hash
      }
      File.write("tmp/metadata.json", metadata.to_json)
      metadata_io = Faraday::UploadIO.new("tmp/metadata.json", 'application/json')
      ok, metadata_ipfs_hash = send_file(metadata_io)
      collection.update(image_hash: image_ipfs_hash, metadata_hash: metadata_ipfs_hash)
      ok ? metadata_ipfs_hash : nil
    end

I’m getting the following error even though the region is set

ERROR: No region was provided. Configure the `:region` option or export the region name to ENV['AWS_REGION']

I am not an expert on rails. I’ve worked with .NET MVC for more than 5 year and I searched for solutions that I’d implement if I’d use it .NET but I haven’t found the solution yet.

That’s why I’m requesting your help

Regards!


Submit an answer

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer