2010-11-09 33 views
1

我在服務器上使用Paperclip附加到模型類上的字節流,我希望能夠指定它們作爲文件系統保存的名稱。因爲我有很多這些傳入文件,所以我希望能夠將它們創建爲Tempfiles,這樣我就不必擔心名稱衝突並手動刪除它們等。這是我在做什麼:如何使用Paperclip爲我的附件指定文件名?

desired_file_name = 'foo.txt' 
Tempfile.open([File.basename(desired_file_name), File.extname(desired_file_name)]) do |tf| 
    tf.write(content_stream) 
    tf.rewind 
    model_obj.paperclip_attachment = tf 
end 

這幾乎工作。唯一的問題是,我的Paperclip附件最終會得到一個臨時文件名稱,如foo.txt.201029392u-gyh-foh96y.txt。那麼,我該如何告訴Paperclip將我的文件保存爲?調用model_obj.paperclip_attachment_file_name = desired_file_name不起作用。數據庫字段被保存爲該名稱,但在文件系統上,我仍然有該臨時文件名稱。

回答

7

我認爲你可以定義自己的插值interpolation來做到這一點。然後您可以正常附加文件。例如:

# config/initializers/paperclip.rb 
Paperclip.interpolates :custom_filename do |attachment, style| 
    # Generate your desired file name here. 
    # The values returned should be able to be regenerated in the future because 
    # this will also be called to get the attachment path. 

    # For example, you can use a digest of the file name and updated_at field. 
    # File name and updated_at will remain the same as long as the file is not 
    # changed, so this is a safe choice. 
    SHA1.sha1("#{attachment.original_filename}-#{attachment.updated_at}") 
end 

# app/models/post.rb 
class Post < ActiveRecord::Base 
    has_attached_file :attachment, 
    :path => ':rails_root/public/system/:class/:attachment/:id/:style/:custom_filename', 
    :url => '/system/:class/:attachment/:id/:style/:custom_filename' 
end 

請注意,這隻會更改文件系統中的文件名。 model.attachment_file_namemodel.attachment.original_filename仍將保留原始文件名稱。

+0

謝謝,這工作!唯一我不太明白(也沒有實現)的是你爲什麼建議使用散列函數。我想保留desired_file_name。包含該id的文件的路徑應確保唯一性。 – Jeff 2010-11-09 18:17:45

+0

散列函數是使文件名不可猜測,所以人們不能猜測的URL(附件/ 1,附件/ 2等),並下載所有的文件。使用id和文件名也應該達到同樣的效果,但是對我來說使用hash的好處是沒有必須被URL轉義的字符。 – htanata 2010-11-10 04:06:03

相關問題