Skip to content

Instantly share code, notes, and snippets.

@carlosipe
Last active December 16, 2015 16:40
Show Gist options
  • Save carlosipe/5465086 to your computer and use it in GitHub Desktop.
Save carlosipe/5465086 to your computer and use it in GitHub Desktop.
CarrierWave ImageUploader, thumb resizing on the fly
# encoding: utf-8
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
# storage :fog
# Process files as they are uploaded (if width >1024):
process :resize_to_limit =>[1024, 10000]
def thumb(size)
return default_url if url == default_url
uploader = Class.new(self.class)
uploader.version_names = [size]
img = uploader.new(model, mounted_as)
img.retrieve_from_store!(identifier)
cached = File.join(CarrierWave.root, img.url)
unless File.exist?(cached)
img.cache!(self)
size = size.split('x').map(&:to_i)
resizer = case size
when /[!#]/ then :resize_to_fit
# add more like when />/ then ...
else :resize_to_fill
end
img.send(resizer, *size)
img.store!
#puts 'RESIZING'
end
img
end
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def default_url
"/assets/defaults/#{model.class.to_s.underscore}.png" #[version_name, "esparrago.jpg"].compact.join('_')
end
# def extension_white_list
# %w(jpg jpeg gif png)
# end
end
@carlosipe
Copy link
Author

TODO:

  • Handle thumbnails when image is not provided (versions of default_url)
  • Extension white_list: find out how to use open_uri and preserve the file extenision (in seeds.rb) to make that validation pass.

@carlosipe
Copy link
Author

Actually, I think it's a bad idea to return a default_url, because the choice of using a default image normally belongs to the view domain, not to the model (or uploader class).
I should add a method "fallback" but still be able to receive a nil when trying to do image_tag p.picture.
This two helpers might be useful:

def img_w_fallback(p)
image_tag( p.nil? ? p.fallback : p)
end

def thumb_w_fallback(p, size)
image_tag( p.nil? p.fallback.thumb(size) ? p.thumb(size)
end

I still need a way to make thumbs of default, but I don't want to serve it transparently, but letting the choice to the view helper.

@carlosipe
Copy link
Author

Btw, I should serve the files over a CDN, or at least a cookieless domain

@carlosipe
Copy link
Author

Another idea: resizing by url (example, to offer an api or to work easily on javascript)

ResizerController

def index
model, id, mounted_as, operation, args = params[:url].split '/'
Class.new(model.constantize).find(id).send(mounted_as, *operation, args) || raise 404
end

//If the file already exists, nginx won't call Rails, if find fails, ActiveRecord raises an exception that produces 404, if the result of the operation is nil, I raise a 404, if it's not nil is an image_url

Controller should validate acceptable operations and args (to stop DDOS), it can also require a token.

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