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!