簡體   English   中英

rails paperclip S3具有動態存儲桶名稱

[英]rails paperclip S3 with dynamic bucket name

我正在使用paperclip將我的文檔上傳到Amazon S3。 我想在上傳新文檔時自動創建一個包含項目ID的存儲桶。

因此,在我的控制器中,我有這個:

 def new
    @pmdocument = Pmdocument.new
    @pmdocument.projectmilestone_id=params[:projectmilestone_id]

其中projectmilestone_id是我項目的foreign_key(用作我的桶名)

我的模型是這樣的:

class Pmdocument < ActiveRecord::Base
  belongs_to :projectmilestone
  attr_accessible :id, :name, :description, :projectmilestone_id, :pmdoc, :projectmilestone_attributes
  attr_protected :pmdoc_content_type, :pmdoc_size
  accepts_nested_attributes_for :projectmilestone, :allow_destroy => false
  has_attached_file :pmdoc,
    :storage => :s3,
    :bucket => self.projectmilestone_id.to_s,
    :s3_credentials => File.join(Rails.root, 'config', 's3.yml')

當我加載頁面時,我收到此錯誤:未定義的方法`projectmilestone_id'for#

我檢查了我的控制器,並在那里正確加載了projectmilestone_id字段。

我試圖將存儲桶行更改為:bucket => self.name ,然后錯誤消失了。

該模型工作正常,因為projectmilestone_id正確存儲在db中。

我的猜測是它可以鏈接到可訪問的屬性,但它似乎也可以。

怎么了? 非常感謝!!!


我真的不明白:

我決定不再改變我的桶了(不管怎樣,壞主意因為所有S3的名稱都必須是唯一的),而是改變我的路徑。

這是代碼:

:path => proc { |attachment| "#{attachment.istance.projectname}/:attachment/:id/:basename.:extension" },

未創建具有項目名稱的第一個文件夾。 如果我按名稱,甚至描述(pmdocuments的另一個字段)替換projectname,它可以工作,但不能與projectname一起使用。 當然,我檢查了projectname是否正確填充。 原因在於其他地方。

任何線索?

has_attached_file方法在類的上下文中執行(在加載文件時),而不是在可以使用屬性和其他實例方法的記錄實例的上下文中執行。 self.name確實有效,但它返回類的名稱( "Pmdocument" ),而不是記錄的名稱。

但Paperclip非常友好,可以滿足您的需求。 有關S3存儲文檔說:

如果要在運行時確定其名稱,可以將存儲桶定義為Proc。 Paperclip會將附件作為唯一參數調用Proc。

在你的情況下,它將是這樣的:

has_attached_file :pmdoc,
  :storage => :s3,
  :bucket => proc { |attachment| attachment.instance.projectmilestone_id.to_s },
  :s3_credentials => File.join(Rails.root, 'config', 's3.yml')

現在您將Proc has_attached_file 在加載類時不會評估塊的內容,但在以后需要時會對其進行評估。 然后,Paperclip使用附件作為參數調用塊,並將返回的值用作存儲桶名稱。

編輯:

不幸的是,這個塊在分配文件時運行,而不是在保存記錄時運行。 因此,您的所有屬性可能尚未設置(當您執行Pmdocument.new(params[:pmdocument])屬性分配的順序未確定。 我想讓Paperclip以另一種方式工作,但與此同時我看到兩個選擇:

您可以從控制器中的參數中刪除該文件,並在其他所有准備就緒時設置該文件:

pmdoc = params[:pmdocument].delete(:pmdoc)
@pmdocument = Pmdocument.new(params[:pmdocument])
@pmdocument.pmdoc = pmdoc

或者,您可以通過使用before_post_process禁用Paperclip后處理(請參閱README的“事件”部分)並在after_save回調中運行它來延遲Paperclip后處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM