The class below has a Paperclip attachment that is stored on S3. The attachment has a custom processor that takes dimensions and crops the image from user defined points. There is a need to move this post-processed attachment from one contact to another, and the copy_avatar_to
methods accomplishes this without reprocessing the attachment. Reprocessing would result in the cropping points being lost, and the original image source being copied over, and resized according to the styles.
# avatar_content_type :string(255)
# avatar_file_name :string(255)
# avatar_file_size :integer
# avatar_updated_at :datetime
class Contact < ActiveRecord::Base
has_attached_file :avatar
:processors => [:cropper], :storage => :s3,
:s3_credentials => "#{Rails.root.to_s}/config/s3.yml",
:path => ":contact_account_id/avatars/:id_:hash_:style.:extension",
:hash_data => ":class/:attachment/:id/:style",
:styles => { :tiny => "15x15#", :small => "25x25#", :medium => "75x75#", :large => "200x200>"}
attr_accessor :crop_x, :crop_y, :crop_width, :crop_height
before_update :reprocess_avatar, :if => :cropping?
# Copies an avatar from one contact to another contact
# e.g. contact_a (has avatar)
# contact_a.copy_avatar_to(contact_b)
# This doesn't reprocess the avatar, but copies the S3 objects directly
# Because we don't call reprocess!, we don't have to persist any cropping data
def copy_avatar_to(contact)
# Setup a dummy avatar for the contact passed
# This will setup the S3 objects for each style defined in the attachment :styles key
contact.update_attribute(:avatar, avatar)
# For each attachment, call "copy_from", passing the source, and permissions
avatar.styles.keys.push(:original).each do |style|
# Documentation at aws-sdk gem, lib/aws/s3/s3_object.rb:495
contact.avatar.s3_object(style).copy_from avatar.s3_object(style),
{ acl: avatar.s3_permissions(style) }
end
end
end
Contact.first.copy_avatar_to(Contact.last)