CarrierWave on Heroku
As the new hotness in file attachments, CarrierWave (http://github.com/jnicklas/carrierwave) provides a really slick and easy way to attach files to your models. It presents an issue if you run on Heroku, however, since CarrierWave stores temporary files in public/uploads/tmp by default. It uses these temp files when the form is redisplayed so the uploads are not lost. It is a cool feature, but a hassle if you are on Heroku since those folders are not writable.
Heroku does provide a place for you to keep temporary files though. You can configure CarrierWave to use a custom cache dir by adding to your uploader:
def cache_dir
"#{RAILS_ROOT}/tmp/uploads"
end
CarrierWave will then use one of the temp folders provided by Heroku and you will be able to use the temporary files in future requests. We still have the problem of being able to display the images when the form is redisplayed though. It is a pretty awesome feature that we don't want to miss out on and luckily we don't have to.
To be able to serve up the temporary images from the tmp folder, you need to make an additional action on one of your controllers that will take the cache location as a parameter and return the image.
Put this in the resource's controller to respond with the image:
def image_cache headers['Cache-Control'] = 'public; max-age=600' # cache image for 10 minutes send_file "#{RAILS_ROOT}/tmp/uploads/#{params['cache_id']}/#{params['filename']}", :disposition => 'inline', :type => "image/png" endPut this in your routes file (where resource is the controller your new action is in):
map.resource_image_cache '/resources/image_cache', :controller => 'resources', :action => 'image_cache', :requirements => { :cache_id => /\d{8}-\d{4}-\d{5}-\d{4}/, :filename => /[a-zA-Z0-9_ ]+\.(jpg|jpeg|png|gif){1}/i } And reference it like this in your view (where avatar is the field you mounted the uploader on):
= image_tag(resource_image_cache_path(:cache_id => resource.avatar_cache[/^[\d-]+/], :filename => resource.avatar_cache[/[a-zA-Z0-9 _\.]+$/])) if resource.avatar_cacheSpecial thanks to fellow Rocketeer Shay ( https://twitter.com/shayarnett ) for his input on this post.