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
Answer a question...

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