Whenever I save a model with a mounted uploader, the versions get deleted whenever I save it (and it appears as if the versions are not even created when uploading an image normally). Note that it used to work fine until a few days/weeks ago (I didn’t notice the exact time although it may have happened by moving to Rails 3.2.11. I was at 3.2.8 before).
My model is defined like this:
class Profile < ActiveRecord::Base
attr_accessible :profile_picture
mount_uploader :profile_picture, ProfilePictureUploader
...
end
And my ProfilePictureUploader:
class ProfilePictureUploader < BaseUploader
process :resize_to_fill => [248, 248]
version :tiny do
process :resize_to_fill => [34, 34]
def full_filename(for_file = model.photo.file)
"#{model.to_s.parameterize}_tiny.jpg"
end
end
def extension_white_list
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename
# John Snow -> john-snow-20120913162935.jpg
# ACME inc. -> acme-inc-20120913162935.png
"#{model.to_s.parameterize}-#{Time.now.strftime("%Y%m%d%H%M%S")}#{File.extname(original_filename)}" if original_filename
end
end
And finally my BaseUploader:
class BaseUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
# Override the directory where uploaded files will be stored.
def store_dir
"system/uploads/#{model.class.to_s.underscore}/#{model.id}"
end
# Override the filename of the uploaded files:
def filename
"#{mounted_as}#{File.extname(original_filename)}" if original_filename
end
end
I use file store in development and fog storage in production, but the issue occurs in both environments so let’s just assume it’s using file storage.
Here’s my typical scenario:
- I upload an image to a Profile, only the standard image gets created (ex:
mbillard-20130122102833.jpg). - I call
recreate_versions!on the profile picture, both the standard image and the tiny version get created (the standard is recreated because of my particular naming scheme, I’m fine with that). - I save my model, everything in the folder (
system/uploads/profile/1/) gets deleted except the image with the filename of theprofile_pictureattribute.
I use carrierwave 0.8.0. I believe it has to do with a save trigger, but couldn’t figure it out by looking at the code.
(I have also opened a GitHub issue in parallel)
I finally figured it out. Basically, it seems like the
remove_previously_stored_#{column}method inmount.rbremoved my newly created versions because they had the same name as the previous versions.I modified my tiny version filename to include the timestamp (so that it wouldn’t have the same filename as the previous tiny version):
I simplified my
filenamelogic to simple define a filename with the timestamp:And my timestamp functions either extracts the timestamp from the filename or generates a new one when recreating versions or uploading a new file (when original_filename is present):
Note that the previous timestamp could be stored in an attribute on my model, but this works for me.
The only thing that annoys me now is that I have to save my model in order for the previous files to be deleted when recreating versions.
You can see my whole thought process over at the GitHub issue.