Rails 4 and paperclip - Stop the :original style file upload to copy it from an S3 remote directory

随声附和 提交于 2019-12-02 08:07:05

New Answer:

paperclip attachments get uploaded in the flush_writes method which, for your purposes, is part of the Paperclip::Storage::S3 module. The line which is responsible for the uploading is:

s3_object(style).write(file, write_options)

So, by means of monkey_patch, you can change this to something like:

s3_object(style).write(file, write_options) unless style.to_s == "original" and @queued_for_write[:your_processed_style].present?

EDIT: this would be accomplished by creating the following file: config/initializers/decorators/paperclip.rb

Paperclip::Storage::S3.class_eval do
  def flush_writes #:nodoc:
    @queued_for_write.each do |style, file|
    retries = 0
      begin
        log("saving #{path(style)}")
        acl = @s3_permissions[style] || @s3_permissions[:default]
        acl = acl.call(self, style) if acl.respond_to?(:call)
        write_options = {
          :content_type => file.content_type,
          :acl => acl
        }

        # add storage class for this style if defined
        storage_class = s3_storage_class(style)
        write_options.merge!(:storage_class => storage_class) if storage_class

        if @s3_server_side_encryption
          write_options[:server_side_encryption] = @s3_server_side_encryption
        end

        style_specific_options = styles[style]

        if style_specific_options
          merge_s3_headers( style_specific_options[:s3_headers], @s3_headers, @s3_metadata) if style_specific_options[:s3_headers]
          @s3_metadata.merge!(style_specific_options[:s3_metadata]) if style_specific_options[:s3_metadata]
        end

        write_options[:metadata] = @s3_metadata unless @s3_metadata.empty?
        write_options.merge!(@s3_headers)

        s3_object(style).write(file, write_options) unless style.to_s == "original" and @queued_for_write[:your_processed_style].present?
      rescue AWS::S3::Errors::NoSuchBucket
        create_bucket
        retry
      rescue AWS::S3::Errors::SlowDown
        retries += 1
        if retries <= 5
          sleep((2 ** retries) * 0.5)
          retry
        else
          raise
        end
      ensure
        file.rewind
      end
    end
    after_flush_writes # allows attachment to clean up temp files
    @queued_for_write = {}
  end
end

now the original does not get uploaded. You could then add some lines, like those of my origninal answer below, to your model if you wish to transfer the original to its appropriate final location if it was uploaded to s3 directly.

Original Answer:

perhaps something like this placed in your model executed with the after_create callback:

    paperclip_file_path = "relative/final/destination/file.jpg"
    s3.buckets[BUCKET_NAME].objects[paperclip_file_path].copy_from(relative/temp/location/file.jpg)

thanks to https://github.com/uberllama

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!