[英]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.