Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Associate object to pre-existing file on S3, using Paperclip

I have a file already on S3 that I'd like to associate to a pre-existing instance of the Asset model.

Here's the model:

class Asset < ActiveRecord::Base
  attr_accessible(:attachment_content_type, :attachment_file_name,
                 :attachment_file_size, :attachment_updated_at, :attachment)

  has_attached_file :attachment, {
    storage: :s3,
    s3_credentials: {
      access_key_id: ENV['AWS_ACCESS_KEY_ID'],
      secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
    },
    convert_options: { all: '-auto-orient' },
    url: ':s3_alias_url',
    s3_host_alias: ENV['S3_HOST_ALIAS'],
    path: ":class/:attachment/:id_partition/:style/:filename",
    bucket: ENV['S3_BUCKET_NAME'],
    s3_protocol: 'https'
  }
end

Let's say the path is assets/attachments/000/111/file.png, and the Asset instance I want to associate with the file is asset. Referring at the source, I've tried:

options = {
    storage: :s3,
    s3_credentials: {
      access_key_id: ENV['AWS_ACCESS_KEY_ID'],
      secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
    },
    convert_options: { all: '-auto-orient' },
    url: ':s3_alias_url',
    s3_host_alias: ENV['S3_HOST_ALIAS'],
    path: "assets/attachments/000/111/file.png",
    bucket: ENV['S3_BUCKET_NAME'],
    s3_protocol: 'https'
  }
# The above is identical to the options given in the model, except for the path

Paperclip::Attachment.new("file.png", asset, options).save

As far as I can tell, this did not affect asset in any way. I cannot set asset.attachment.path manually.

Other questions on SO do not seem to address this specifically. "paperclip images not saving in the path i've set up", "Paperclip and Amazon S3 how to do paths?", and so on involve setting up the model, which is already working fine.

Anyone have any insight to offer?

like image 768
Simon Lepkin Avatar asked Sep 30 '22 20:09

Simon Lepkin


1 Answers

As far as I can tell, I do need to turn the S3 object into a File, as suggested by @oregontrail256. I used the Fog gem to do this.

s3 = Fog::Storage.new(
        :provider => 'AWS',
        :aws_access_key_id => ENV['AWS_ACCESS_KEY_ID'],
        :aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
      )

directory = s3.directories.get(ENV['S3_BUCKET_NAME'])
fog_file = directory.files.get(path)

file = File.open("temp", "wb")
file.write(fog_file.body)
asset.attachment = file
asset.save
file.close
like image 86
Simon Lepkin Avatar answered Oct 03 '22 10:10

Simon Lepkin