Randomize Filename in Paperclip
by Trevor Turk
Here’s a quick tip that Jonathan Yurek, author of Paperclip, was kind enough to help me with. It’s a simple way to have a randomized filename for uploaded content. This is useful for security through obscurity, especially when used with Paperclip’s id_partition interpolation helper:
class Photo ":class/:attachment/:id_partition/:basename_:style.:extension"
before_create :randomize_file_name
private
def randomize_file_name
extension = File.extname(image_file_name).downcase
self.image.instance_write(:file_name, "#{ActiveSupport::SecureRandom.hex(16)}#{extension}")
end
end
That would, for example, change an uploaded image named “DS_100.JPG” into:
http://example.com/photos/images/000/001/204/e15f64f5e7gjdo3e4ae58f4ed9j925f5.jpg
That makes it effectively impossible to guess the location of an image, provided that you don’t allow people to browse around the directories on your server. This is the same method of privacy protection that Flickr uses, and it ought to be enough for most non-governmental privacy needs
Thanks for sharing! This is indeed useful.
I patched your code and found this more useful in my project:
def randomize_file_name
return if image_file_name.nil?
extension = File.extname(image_file_name).downcase
if image_file_name_changed?
self.image.instance_write(:file_name, "#{ActiveSupport::SecureRandom.hex(16)}#{extension}")
end
end
Thanks, the second example works like a charm.
[...] key bit is using the attachment’s #instance_write method, as suggested by Trevor Turk for a slightly different [...]
the problem of this method is if you have a validation in your model, then it fail …
to fix this i use before_post_process :randomize_file_name instead of before_create :randomize_file_name