使用Paperclip将对象关联到S3上的预先存在的文件

时间:2014-05-08 04:23:35

标签: ruby-on-rails ruby-on-rails-3 amazon-s3 paperclip fog

我已经在S3上有一个文件,我希望将其关联到预先存在的Asset模型实例。

这是模特:

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

我们说路径为assets/attachments/000/111/file.png,我要与文件关联的Asset实例为asset。在source上提到,我试过了:

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

据我所知,这不会以任何方式影响asset。我无法手动设置asset.attachment.path

关于SO的其他问题似乎没有具体解决这个问题。 &#34; paperclip images not saving in the path i've set up&#34;,&#34; Paperclip and Amazon S3 how to do paths?&#34;等等涉及设置模型,该模型已经正常工作。

任何人都可以提供任何见解?

2 个答案:

答案 0 :(得分:3)

据我所知,我需要将S3对象转换为File,如@ oregontrail256所示。我使用Fog gem来做到这一点。

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

答案 1 :(得分:1)

Paperclip附件具有copy_to_local_file()方法,允许您制作附件的本地副本。那么:

file_name = "temp_file"
asset1.attachment.copy_to_local_file(:style, file_name)
file = File.open(file_name)
asset2.attachment = file
file.close
asset2.save!

即使您销毁asset1,您现在也可以分别获得asset2保存的附件副本。如果您正在做很多这样的工作,您可能希望在后台工作中这样做。

也赞同这个答案:How to set a file upload programmatically using Paperclip