Report this

What is the reason for this report?

Retrieve image from Space AWS S3 ERROR

Posted on June 30, 2022

Hi everyone,

I have a rails application that allows users to upload an image and then this image is uploaded to IPFS. We are using ActiveStorage and storing the image in a local folder.

To go to production I have decided to try Space by Digital Ocean.

The file is uploading correctly to Space, but when I want to upload it to IPFS I get an error because the image is no longer stored locally.

I got the following error. It’s because now I’m using “S3” service instead of “Disk”

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

We’re getting the error in this function

    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

upload function is being called by create function

  def create
    begin
        @collection = Collection.new(collection_params)
        @collection.state = :pending
        @collection.address = Collection.generate_uniq_token
        @collection.creator_id = current_user.id
        @collection.owner_id = current_user.id
        @collection.data = JSON.parse(collection_params[:data]) if collection_params[:data].present?
        @collection.owned_tokens = @collection.no_of_copies
        if @collection.valid?
          @collection.save
          @metadata_hash = Api::Pinata.new.upload(@collection)
        else
          @errors = @collection.errors.full_messages
        end
    rescue Exception => e
      Rails.logger.warn "################## Exception while creating collection ##################"
      Rails.logger.warn "ERROR: #{e.message}, PARAMS: #{params.inspect}"
      Rails.logger.warn $!.backtrace[0..20].join("\n")
      @errors = e.message
    end
  end

The storage.yml looks like

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"

I was trying to retrieve the image from the Space using AWS S3. I added the following code within the create function

 s3 = Aws::S3::Client.new
 resp = s3.get_object(bucket: 'stg-vikuimages', key: attachment.key)
 respBody = resp.body

I’m getting this error even though I set the region as it’s shown in the file storage.yml

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

I have almost no experience with rails. That is why I require your help.

Regards!



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!

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.