Question

Retrieve image from Space AWS S3 ERROR

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!


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