2012-12-31 97 views
3

我一直在搜索這個網站,但似乎無法找到構建圖像和文件上傳的文件夾/文件的最佳方式。我部署使用Ruby on Rails的網站:CarrierWave文件夾結構最佳實踐

  • CarrierWave(上傳)
  • Capistrano的(部署)
  • 亞馬遜S3(存儲)
  • Capistrano的(部署)

網站允許用戶設置他們將要上傳圖像的配置文件。我想使用能夠很好地擴展到上千張(或數萬)用戶上傳多張圖片的文件夾結構。

目前我使用的是默認CarrierWave目錄結構:

def store_dir 
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 
end 

但我想這是更好地也許包括文件夾名稱user_ID的?將此文件夾移動到public/uploads文件夾之外更好嗎?我不應該爲開發,生產和測試環境使用不同的文件夾嗎?我想以最佳方式覆蓋store_dir,這個網站有數千個用戶上傳每個配置文件大約15個文件(存儲爲完整大小,配置文件和縮略圖大小)。

+0

請理解我已經搜索了這一大堆,並希望我尊重這個網站上的規則 - 我很少需要問純粹的編碼問題,因爲這個網站上已經有很棒的答案。任何有關文件夾/文件結構的好建議或部署提示都將被接受爲答案。 – FireDragon

回答

8

正常的文件夾結構應該非常好地支持帽子,主要是避免衝突並確保您在網站上使用的圖片關聯是一致的。由於這些原因,您不希望將所有圖像都顯示在一個文件夾中。

但我想這可能包括在文件夾名稱user_id更好?

我不會推薦這個,它可能會導致比它的價值更多的問題。使用模型類和標識符應該足夠充分,並且上傳器可能在映射映像時遇到問題,例如,當不是上傳器的用戶嘗試查看映像時。

將public文件夾移動到public/uploads文件夾之外更好嗎?

由於您使用的是Amazon S3,因此您的圖像實際上並不存儲在項目的公共/上傳中(如果這是您所指的位置)。這應該只是Carrierwave在上傳/調整文件大小時使用的臨時文件。如果您擔心空間/安全問題,您可能需要查看this,並根據需要調整它以適應您的需求。

我不應該爲開發,生產和測試環境使用不同的文件夾嗎?

您可以使用不同的文件夾,如果你喜歡:

def store_dir 
    "#{Rails.env}/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 
end 

或者Amazon S3上使用不同的桶(推薦):

config/initializers/fog.rb類似:

CarrierWave.configure do |config| 
    config.storage = :fog 
    config.fog_credentials = { 
    :provider    => <provider>, 
    :aws_access_key_id  => <id>, 
    :aws_secret_access_key => <key> 
    } 
    if Rails.env == "production" 
    config.fog_directory = 'production' 
    elsif Rails.env == "development" 
    config.fog_directory = 'development' 
    elsif ... 
    config.fog_directory = '...' 
    end 
end 

或者你可以在單獨的環境文件中做類似的事情。

我想以最佳方式覆蓋store_dir,這個網站有成千上萬的用戶上傳每個配置文件大約15個文件(存儲爲全尺寸,配置文件和縮略圖大小)。

這個存儲目錄結構應該工作得很好,只要調整大小,你應該檢查出the guide

更新:

對於文件的名字,我肯定會建議其更改爲一個隨機字符串,這樣就可以避免文件夾本身的任何潛在的命名衝突。有人可能爲2個不同的文件上傳me.jpg並不是不可能的。這就是說這是我如何做到這一點。

your_uploader.rb

添加一個文件名的方法,將隨機當前的文件名。

def filename 
    random_token = Digest::SHA2.hexdigest("#{Time.now.utc}--#{model.id.to_s}").first(20) 
    ivar = "@#{mounted_as}_secure_token" 
    token = model.instance_variable_get(ivar) 
    token ||= model.instance_variable_set(ivar, random_token) 
    "#{token}.jpg" if original_filename 
    end 

這種特殊的安排可能有點矯枉過正,但它對我來說足夠了。

希望這會有所幫助!

+0

這是非常有用的傑森我將在未來幾天內實施,並讓你知道它是如何發展的。 – FireDragon

+0

我的一個問題是,如果最好保留上傳文件的原始文件名?意思是說,如果有人上傳「some-long-filename.jpg」,只需保留這個名字或者正常就可以將文件重命名爲諸如「12345.jpg」之類的數字。我剛剛注意到在某些網站上重命名。 – FireDragon

+2

我會爲此更新答案。我肯定會推薦改變它。 –