In my last blog about paperclip I described the rotation of images.
Since I have added more styles with different sizes for the attachment, I got some performance problems, because for every image, 7 sizes has to be reprocessed and this took a long of time.
My solution is, to handle the reprocessing in background with delayed_job and aasm (acts_as_state_machine).
Media-Model
This is the “normal” Media-Model. First at all, there is AASM included, to see the current state (pending, error, ready) of processing. Furthermore, to show the image, I create a url method, which give back the path to the image (if the state is :ready) or an placeholder (if the state is NOT :ready).
media.rb
class Media
has_attached_file( :source,
:styles => {
:bigger => '1600x1600>',
:big => '800x600>',
:album => '560x420>',
:album_preview => '150x150>',
:album_folder => '70x70#',
:profile => '180x250>',
:avatar => '50x50#' },
:storage => :filesystem,
)
include AASM
aasm_column :status
aasm_initial_state :pending
aasm_state :pending
aasm_state :error
aasm_state :ready
aasm_event :converted do
transitions :to => :ready, :from => [:pending]
end
def url(style = :original)
if(self.ready?)
source.url(style)
else
# Image is processing, please wait
Media.find(3).source.url(style)
end
end
end
The “Uploading” Media-Model
For uploading new images, the model MediaUpload will be used.
This model inherits from the Media-Model, but the paperclip configuration will be overriden.
There is only one style available, because it’s the feedback image for the uploading user.
After saving the image, a new MediaJob will be created in background with the help of delayed_job.
media_upload.rb
class MediaUpload < Media
# paperclip
has_attached_file( :source,
:styles => { :avatar => '50x50#' },
:storage => :filesystem
)
after_create :create_all_styles
def create_all_styles
Delayed::Job.enqueue MediaJob.new(self.id)
end
end
The REPROCESSOR
At least, the media-job created all styles for the image …and it’s DONE.
media_jobs.rb
class MediaJob < Struct.new(:id)
def perform
m = Media.find(id)
m.source.reprocess!
end
end
Helpful links: