Copy All Styles of a Paperclip Attachment to New Object (S3)

放肆的年华 提交于 2019-12-23 20:17:09

问题


I have a model that uses Paperclip to handle images. When the image gets uploaded a preview is made for some javascript cropping and then a thumbnail and preview sizes are made from the chosen cropping. Giving us 3 images on S3 total:

  • Original Image
  • Preview (from the user selected cropping)
  • Thumb (from the user selected cropping)

The code in the model for the attachment is:

has_attached_file :picture, ASSET_INFO.merge(
  :whiny => false,
  :styles       => { :thumb => '200>x200#', :preview => '400x300>' },
  :processors   => [:jcropper],
  :preserve_files => true
)

We have some functionality that allows a user to make a copy of an object for their own purposes and we want to copy the images over. I thought that just doing a simple

new_my_model.picture = original_my_model.picture if original_my_model.picture_file_name #no file name means no picture

would get the job done, and it does, but only kind of.

It's copying the picture and then reprocessing the preview and thumbnails based on what's set up in the model.

What I would like to do instead is copy all 3 existing images (original, thumb, and preview) to the new object as they are for the original one and then save them in the appropriate location on S3, skipping the resizing/cropping.

Can anyone point me in the right direction? I've searched online and can't seem to find anything and everything I try doesn't seem to work. Doing a .dup on the original picture causes an exception, so that idea is out.


回答1:


Manual cropping breaks Paperclip's automatic cropping/resizing scheme. That's okay until you want to duplicate an attachment from one model to another. You have two options: Save the cropping parameters for each style in database, and call "reprocess!" after duplicating (based on the this question).

I have no intention to save cropping data in database, it's totally useless. I decided to blindly duplicate the images myself, directly calling S3. Not optimal, but works:

module Customizable

  def duplicate copy_args
    new_model = self.dup
    copy_args.each {|key, val| new_model[key] = val}
    new_model.save

    s3 = AWS::S3.new(self.image.s3_credentials)
    bucket = s3.buckets[self.image.s3_credentials[:bucket]]

    styles = self.image.styles.keys.insert(0, :original)

    begin
      styles.each do |style|
        current_url = self.image.path(style)
        current_object = bucket.objects[current_url]
        if current_object.exists?
          # actually asking S3 if object exists
          new_url = new_model.image.path(style)
          new_object = bucket.objects.create(new_url)
          # this is where the copying takes place:
          new_object.copy_from(current_object)
          new_object.acl = current_object.acl
        end
      end
    rescue Exception => err
      return err
    end

    return true
  end

end

In my model:

class Product < ActiveRecord::Base

  # ...
  has_attached_file :image, ...
  # ...
  include Customizable

  def customize product_id
    return self.duplicate({:in_sale => false}) #resetting some values to the duplicated model
  end

  # ...
end


来源:https://stackoverflow.com/questions/17603045/copy-all-styles-of-a-paperclip-attachment-to-new-object-s3

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