-
Notifications
You must be signed in to change notification settings - Fork 1.7k
How to: prevent carrierwave from locking the db row of your object while it's processing the image attached to that object
In the normal CarrierWave setup, image processing kicks off when you .save!
the ActiveRecord object. Because of this a SQL transaction stays open the entire time the image is processing. Image processing can take awhile, especially if you have multiple image formats, are downloading & uploading from S3, etc. If your application wants to make any updates to the object's DB row while it's image attachment is being processed you need to change the way you cannot use this ActiveRecord post-save! hook.
This is the standard way to process remote images:
def process!( url )
self.remote_file_url = url
save!
end
You can re-work it like this to avoid the transaction lock:
user.pending_process_url = 'http://...'
class User < ActiveRecord::Base
mount_uploader :pic, FileUploader
...
def process!
return if pending_process_url.nil?
f = FileUploader.new
f.download!( pending_process_url ) # from s3 > /tmp
f.store!
self['pic'] = CGI.unescape( pending_process_url ).split('/').last
self.pending_process_url = nil
save!
end
end
As an extra bonus, if you are downloading & uploading images from S3 (for example, if you use plupload as your uploader) then you can save re-uploading the master image back to S3 since it's already there.
user.pending_process_url = 'http://...'
class User < ActiveRecord::Base
mount_uploader :pic, FileUploader
...
def process!
return if pending_process_url.nil?
f = FileUploader.new
f.download!( pending_process_url ) # from s3 > /tmp
f.versions.values.each do |uploader|
uploader.store! # resize & upload to s3
end
self['pic'] = CGI.unescape( pending_process_url ).split('/').last
self.pending_process_url = nil
save!
end
end