2012-06-06 86 views
12

我正在尋找一種解決方案,讓用戶能夠通過一個file_field上傳多個圖像。我已經查找了諸如Jquery文件上傳和Uploadify之類的選項,但尚未遇到一個有效的解決方案。Rails回形針和多個文件上傳

我已經有多個圖像設置,

has_attached_file :asset, 
        :styles => { :large => "640x480", :medium => "300x300", :thumb => "100x100" }, 
        :storage => :s3, 
        :s3_credentials => "#{Rails.root}/config/s3.yml", 
        :path => "/:contributor_id/:listing_name/:filename" 

現在我展示5個個人file_fields

def new 
    @listing = Listing.new 
    5.times {@listing.assets.build } 

    respond_to do |format| 
    format.html # new.html.erb 
    format.json { render json: @listing } 
    end 
end 

我想有

<%= f.file_field :asset, :multiple => true %> 

這允許用戶在文件瀏覽器中選擇多個文件。但是我怎樣才能用嵌套模型處理這些?並讓他們上傳。

回答

34

所以這裏有幾個問題。

首先,Paperclip的has_attached_file方法不是許多文件的關聯。看起來你正在嘗試構建一個「資產」,就好像它是一個Rails關聯。所有回形針都會在表格中放入幾個字段來存儲關於該文件的一些元數據,並且您會爲每個宣告has_attached_file獲得一個附加文件。如果您要附加5個文件,你需要做的是這樣的:

has_attached_file :asset1 
has_attached_file :asset2 
has_attached_file :asset3 
has_attached_file :asset4 
has_attached_file :asset5 

,或者,你可以創建另一個模型只是來存儲文件。例如:

class Listing < ActiveRecord::Base 
    has_many :assets 
end 

class Asset < ActiveRecord::Base 
    belongs_to :listing 
    has_attached_file :picture 
end 

通過這種方式,你可以有連接到一個上市多個資產(你沒有說什麼原來的對象是,所以我只是把它叫做「上市」)。其次,在HTML中不存在多文件上傳的問題(因此,file_field方法不會採用:multiple => true的參數。您必須使用超出Rails內置表單處理的內容if你需要多文件上傳,Uploadify是一個不錯的選擇(我以前使用過)。有一個gem會轉換文件字段以使用uploadify(並且將支持你想要的:multiple => true語法):https://github.com/mateomurphy/uploadify_rails3/wiki。但是,我不能保證它有多好。

我的建議是逐步啓動。通過Flash上​​傳到Rails可能是一個複雜的過程,涉及處理表單中的CSRF元標記和其他字段。首先製作一個允許用戶使用的表單上傳一個文件並通過Paperclip存儲它。然後,可以將has_attached_file聲明分解爲另一個模型,以便可以將一個或多個文件與模型關聯(如上面的多模型代碼塊所示)。然後嘗試添加Uploadify或其他選擇。 Ernie Miller有一個關於整合Uploadify:http://erniemiller.org/2010/07/09/uploadify-and-rails-3/的體面教程。

要開始,請記住has_attached_file只能附加一個文件。當您嘗試撥打@listing.assets時,沒有「資產」。有資產。如果你需要多個文件,你需要自己創建一個單獨的模型並使用Rails的關聯。

+0

我已經有另一個模型創建稱爲「清單」。列出has_many資產。我已經可以上傳多個資源,只是不通過一個「選擇文件」字段。如果任何人都有使用uploadify的很好的例子,那會很棒。我不知道如何做後臺JS處理每個圖像並正確地將它們發佈到服務器。 – kcollignon

+3

您可以在'file_field'中加入':multiple =>「multiple」'',它可以從一個html文件輸入字段(至少在Chrome中)選擇多個文件。我還沒有解決正確管理這些上傳的問題,但我知道post參數包含您挑選並上傳的多個文件的數組。 –

+0

而且你還必須在你的'form_for'中添加':html => {:multipart =>:true}'。 –

2

接受的答案表示,沒有像HTML中的多文件上傳那樣的東西。

<%= f.file_field :files, multiple: true %> 

這允許您選擇多個圖像並將它們作爲數組發送。

如果你有關係Dog has_many ImagesImage has_attachment :file,這樣做是爲了讓多張圖片同時上傳:

在你html.erb

<%= form_for @dog, html: { multipart: true } do |f| %> 
    <%= f.file_field :files, accept: 'image/png,image/jpeg,image/gif', multiple: true %> 
<%= end %> 

在你的控制器

def dog_params 
    params.require(:dog).permit files: [] 
end 

在你的狗模型

def files=(array = []) 
    array.each do |f| 
    images.create file: f 
    end 
end 

這是假設您已經能夠上傳一個圖像,但想要一次升級到多個圖像。注意等待時間會增加。

爲了幫助減少等待時間,偷看我的post對這個問題有關的速度上傳。