Skip to content

Instantly share code, notes, and snippets.

@dblock
Created January 31, 2012 13:55
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dblock/1710609 to your computer and use it in GitHub Desktop.
Save dblock/1710609 to your computer and use it in GitHub Desktop.
Delayed image processing with CarrierWave
CarrierWave.configure do |config|
...
end
Mongoid::Document::ClassMethods.send(:include, DelayedImageProcessing)
module CarrierWave
# http://sleeplesscoding.blogspot.com/2011/09/recreate-single-version-of.html
# Note: is_processing_delayed should be set before calling recreate_version! if the version depends on it.
module Uploader
module Versions
def recreate_version!(version)
already_cached = cached?
cache_stored_file! if !already_cached
send(version).store!
if !already_cached && @cache_id
tmp_dir = File.expand_path(File.join(cache_dir, cache_id), CarrierWave.root)
FileUtils.rm_rf(tmp_dir)
end
end
end
end
# Avoid overwriting original filename in delayed-processing.
module Mount
class Mounter
def write_identifier
if remove?
record.write_uploader(serialization_column, '')
elsif uploader.identifier.present? &&
(!uploader.respond_to?(:is_processing_immediate?) || uploader.is_processing_immediate?)
record.write_uploader(serialization_column, uploader.identifier)
end
end
end
end
end
# A model mounting an uploader with delayed processing should pass delayed: true to the uploader:
# mount_uploader :image, ArtistUploader, delayed: true
# ...and the uploader's versions should be conditional on is_processing_delayed?:
# version :small, :if => :is_processing_delayed? {...}
module DelayedImageProcessing
def mount_uploader(column, uploader=nil, options={}, &block)
delay = options.delete(:delayed)
super
if delay
process_in_background(column)
if uploader && !uploader.include?(DelayedImageProcessing::UploaderMethods)
uploader.send(:include, DelayedImageProcessing::UploaderMethods)
end
end
end
def process_in_background(column = :image)
after_save :"queue_recreate_#{column}_versions!", :if => :"#{column}_file_changed"
attr_accessor :"#{column}_file_changed"
define_model_callbacks :image_processing
class_eval <<-RUBY, __FILE__, __LINE__+1
def queue_recreate_#{column}_versions!
self.#{column}_file_changed = false
self.delay.recreate_#{column}_versions!
end
def recreate_#{column}_versions!
begin
#{column}.is_processing_delayed = true
_run_image_processing_callbacks do
#{column}.recreate_versions!
end
ensure
#{column}.is_processing_delayed = false
end
end
def #{column}=(obj) # track when a new file has been set
super(obj)
self.#{column}_file_changed = true
end
RUBY
end
module UploaderMethods
def is_processing_delayed?(img = nil)
!! @is_processing_delayed
end
def is_processing_immediate?(img = nil)
! is_processing_delayed?
end
def is_processing_delayed=(value)
@is_processing_delayed = value
end
end
end
@dblock
Copy link
Author

dblock commented Jan 31, 2012

All credit for this goes to @Jaghion, (c) Art.sy MIT License. To use add the code from the top gist to config/initializers/carrierwave.rb and place delayed_image_processing.rb somewhere in lib.

@arthurnn
Copy link

I guess the monkey patch is not necessary anymore, as

instance = MyUploader.new
instance.recreate_versions!(:thumb, :large)

is now part of carrierwave. Am I missing something else?

@tommyalvarez
Copy link

How can i adapt this to active record?

@kurenn
Copy link

kurenn commented Apr 9, 2014

I put on a gem together to work with delayed jobs and active record, check it out https://github.com/IcaliaLabs/carrierwave_versions_backgrounder and let me know if you find it useful!

@Mohakjuneja
Copy link

I get this error whenever I'm trying to upload an image - undefined method `delay'
I'm using Mongoid 5.1.0 and uploading the image to Carrierwave using JSON API using this link-
https://gist.github.com/ifightcrime/9291167a0a4367bb55a2

My carrierwave.rb file looks like this -

CarrierWave.configure do |config| #commented configuration for connecting to S3 bucket in production mode end

followed by your code above.

Can you please point out to what I'm doing wrong? Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment