I'm creating an image uploader of sorts, and would like all of the
filenames of uploaded files to be completely random when saved. I am
fairly new to Ruby, Rails, and attachment_fu, and came up with the
following earliar:
def filename=(new_name)
new_name =
"#{Digest::SHA1.hexdigest(Time.now.to_s)}#{File.extname(new_name)}"
write_attribute :filename, sanitize_filename(new_name)
end
end
This works, creating filenames such as
'4de12252220d679aa99b12be835ab56c7a5f7fc9.png', but it doesn't set the
thumbnail name correctly (i.e:
4de12252220d679aa99b12be835ab56c7a5f7fc9_thumb.png) - instead, it
saves it with the same filename
(4de12252220d679aa99b12be835ab56c7a5f7fc9.png).
Does anyone have any ideas on how I can achieve this?
def filename=(new_name)
new_name =
"#{Digest::SHA1.hexdigest(Time.now.to_s)}#{File.extname(new_name)}"
write_attribute :filename, sanitize_filename(new_name)
end
end
This works, creating filenames such as
'4de12252220d679aa99b12be835ab56c7a5f7fc9.png', but it doesn't set the
thumbnail name correctly (i.e:
4de12252220d679aa99b12be835ab56c7a5f7fc9_thumb.png) - instead, it
saves it with the same filename
(4de12252220d679aa99b12be835ab56c7a5f7fc9.png).
The problem is filename= is sometimes called with the filename of the full image and sometimes called with the thumbnail's filename.
The way to solve this is to change the filename right where it enters the system. Remove your filename= method and add this instead to your model:
def uploaded_data=(file_data)
return nil if file_data.nil? || file_data.size == 0
self.content_type = file_data.content_type
self.filename = "#{Digest::SHA1.hexdigest(Time.now.to_s)}#{File.extname(file_data.original_filename)}" if respond_to?(:filename)
if file_data.is_a?(StringIO)
file_data.rewind
self.temp_data = file_data.read
else
self.temp_path = file_data.path
end
end
This is the same as the original implementation but for the third line in the method.