attachment_fu: Saving files with random filenames (using Digest::SHA1)

Hi all,

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:

require 'digest/sha1'

class Photo < ActiveRecord::Base   has_attachment :content_type => :image,                  :storage => :file_system,                  :processor => 'ImageScience',                  :path_prefix => 'public/photos',                  :thumbnails => { :thumb => '100x100>' }   validates_as_attachment

  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?

Thanks.

I figured out how to do it. Here's the code for those who are interested. Seems to work perfect now and generates the thumbnail names how it should.

http://pastie.caboo.se/74792

Rob

Hello,

  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.

Regards, Andy Stewart

I figured out how to do it. Here's the code for those who are interested. Seems to work perfect now and generates the thumbnail names how it should.

http://pastie.caboo.se/74792

Aha! That's the same solution I came up with -- but cleaner. Nice one.

Regards, Andy Stewart