2011-01-11 62 views
2

因此,我正在開發一款應用程序,用戶可以使用附帶的一系列行業特定元數據上傳和管理照片。Rails3,S3,回形針附件,因爲它是自己的模型?

Photo模型包含所有這些元數據,我使用Paperclip將實際圖像文件附加到模型並將圖像存儲在Amazon S3上。

的用戶交互目前是這樣的:

  1. 用戶點擊「添加照片」,並採取在那裏,他提出了一種形式的「新攝影」頁面。
  2. 表單上的第一件事是文件選擇器。用戶選擇一個文件。
  3. 下面是用戶填寫的元數據的幾個不同字段,以便用戶填寫。
  4. 用戶點擊提交,文件上傳並創建一個新的Photo對象,用戶被重定向到不同的頁面。

因此,我想要做的明顯改進是照片在此過程開始時實際上傳,以便在提交和重定向到下一個之間沒有明顯的延遲頁。在完成上傳後,能夠向用戶顯示其照片的縮略圖預覽也很好,以便他們可以在填寫表單時看到他們放入元數據中的照片。

我想我能做到這一點,如果我的圖像文件拆分成自己的模式,但後來我會參考圖像,像這樣:

@photo.attachment.file.url,而不是說我現在使用的簡單@photo.file.url。我寧願不要比我更深入地「嵌套它」。

另外,將它分成兩個模型引發了管理孤兒的問題,這是我目前不必處理的問題。

所以我的問題是:

  1. 有一個好辦法 - 最好使用Flash - 創建而不破此非同步上傳行爲分爲兩個型號,或者 -
  2. 如果我將元數據和文件拆分爲兩個模型,有沒有辦法讓Paperclip將附件當作自己的模型,以便我可以使用<modelname>.<paperclip_method>而不是<model_name>.<attachment_attribute>.<paperclip_method>來訪問它?

我知道這是一個很大的問題,所以非常感謝您的幫助!

回答

1

實驗的一個星期後,我只是想我會發布什麼,我終於做到了:

我其實沒有照片分成兩種型號,因爲我最後不得不與我嘗試任何方法創建空記錄。我發現它到底是比較容易有兩個獨立的模型,因爲:

  1. 這使得它更容易Rails約定範圍內工作(使用標準的REST行動第二模型來處理異步更新,而不必添加幾個自定義操作到父模型)。

  2. 無論我嘗試過哪個選項,我最終都會將孤立記錄視爲一種可能性。我發現有一個父對象,除非有效(在我的情況下是照片模型),並且有可能是孤兒的附件,否則永遠不會保存。附件不會直接在應用程序的任何位置調用,因此不會有意外地將空記錄拉出的風險,也不需要設置默認範圍或某些內容以僅顯示「有效」照片。清理孤兒很簡單,只需要做Attachment.where(:parent_id => nil)並刪除所有這些。

  3. 我可以通過簡單地將附件委託給照片來維護以前的代碼。有關另一個問題,請參閱this answer

我希望這樣可以節省其他人的麻煩。如果您需要附件的Ajax功能,最好將它們製作成自己的模型。另外,爲了將ajax文件上傳到表單,請查看https://github.com/formasfunction/remotipart。這救了我的應用程序。

1

我建議您更換new動作以edit動作(可以當用戶選擇的動作自動創建一個照片的模式。這樣,您就可以使用AJAX文件上傳(支持一些現代瀏覽器)與Flash後備做上傳,也可以編輯元數據。爲做好上傳,嘗試尋找在pluploaduploadify

+0

這很有趣,我沒有想到這一點。你是否複製NEW/CREATE中EDIT/UPDATE動作的代碼,或者是否有一種簡單的方法來告訴NEW動作使用EDIT/UPDATE?另外,我想我只是將所有驗證更改爲「:on =>:update」而不是默認值? – Andrew 2011-01-11 19:58:03

+0

@Andrew我可能會做一個從'新'重定向到一個編輯(初始化和保存一個基本的照片模型後)。至於驗證,是的,你可以將它們移動到更新,但是你可能必須允許大多數字段的空白(因爲它們是更新的AJAX)。 – 2011-01-12 01:11:28

1

有什麼問題簡單地定義,像這樣?

class Photo 
    def url(*args) 
    attachment.url(*args) 
    end 
end 

照片#網址沒有必要在這裏看中。

0

基本上,您將Photo對象的創建分爲兩部分:上傳照片和添加元數據。在非AJAX網站中,這將是兩個單獨頁面上的兩個獨立步驟。

我會做的就是允許AJAX上傳實例化一個Photo對象,並保存它(與上傳的照片)。然後我會讓AJAX代碼返回一個令牌給對應於會話變量的網站,讓表單知道該照片的記錄已經創建完畢。當用戶提交表單的其餘部分時,如果存在該標記,它將知道在已創建的照片對象上填充數據。如果令牌不存在,它會知道它需要從頭開始創建Photo對象。

1

想知道,你是不是在你的關聯中設置依賴子句?例如,

Class Photo < ActiveRecord::Base 
    :has_one :attachment, :dependent => :destroy 
end 

這將防止孤立記錄,作爲一個隨時銷燬方法被調用的照片,它會首先做Photo.attachment.destroy。它也適用於:has_many。