Skip to content

Instantly share code, notes, and snippets.

@crossblaim
Created January 16, 2012 21:24
Show Gist options
  • Save crossblaim/1623116 to your computer and use it in GitHub Desktop.
Save crossblaim/1623116 to your computer and use it in GitHub Desktop.
process paperclip attachments in the background
# == Schema Information
# you need to add a flag to the model to indicate his processing status
# it defaults to true:
#
# attachment_processing :boolean(1) default(TRUE)
# ...
#
#----------------------------------------------------------------------
class Thing < ActiveRecord::Base
# this is the full paperclip configuration, including thumbnail generation
# and s3 uploads, the idea is to execute all this in the background.
has_attached_file :attachment,
styles: {
square_icon: "48x48#",
square_thumb: "150x150#",
big: "650x650>"
},
path: ":id_partition/:random_key_:style.:extension",
s3_credentials: {
access_key_id: AMAZON_ACCESS_KEY,
secret_access_key: AMAZON_SECRET_KEY
},
bucket: BUCKET_NAME,
storage: :s3
# after_attachment_post_process :post_process_attachment
# def post_process_attachment
# ...
# end
end
# temp model
#----------------------------------------------------------------------
class TempThing < Thing
has_attached_file :attachment,
path: ":rails_root/public/system/temp_attachments/:basename.:extension"
after_save :process_in_background
def process_in_background
# I use Resque as the job queue, you can use whatever you want
Resque.enqueue(Jobs::PostProcessThing, self.id)
end
end
# the idea is to use the TempThing model to create a new Thing, this way only the paperclip
# options specified in the TempThing model will be applied, only the original file will be saved
# and the slow thumb generation and s3 uploads will not be executed.
#
# In the Things controller:
def new
@thing = TempThing.new
end
# use the @thing model as usual in the views, just add your multipart form
# Just after the TempThing gets saved, a Job will be queued to be executed later in the background.
#
# In the background job you can do something like this:
temp_thing = TempThing.find(temp_thing_id)
thing = Thing.find(temp_thing_id) # temp_thing and thing are the same record
# the attachment is updated AND processed usng the paperclip config in the Thing model
thing.attachment = temp_thing.attachment.to_file
# we update the processing flag so we can know that the Thing is already processed
thing.attachment_processing = false
thing.save!
path = temp_thing.attachment.path
temp_thing.attachment.to_file.close
File.delete(path) # we can delete the temp attachment now
# in the views you can inmediately display a new uploaded attachment, and since you know
# that the Thing is being processed you can display a "processing" thumb or something like that
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment