2011-06-26 34 views
3

我需要在Rails 3應用上使用一個接口將多個文件上傳到Amazon S3(因爲我在heroku上),可能還有進度條。在Heroku上使用Rails 3和回形針上傳多個文件

我很容易管理如何設置回形針和上傳單個文件,但我現在真的失去了如何繼續前進。

請你能給我一些建議嗎?它的2個天,我正在在所有互聯網搜索,但我無法找到一個有效的解決方案


**編輯**

我實在無法理解......我要去瘋了,因爲我在這上面失去了太多時間......請幫助我。 如果我嘗試打開由約翰尼舉的例子程序,我只得到這個(在我的應用程序是一樣的):

Where is the UI?!

哪裏是UI? 我的瀏覽器有什麼問題嗎?


**編輯2 **

Here on GitHub you can find my testapp ......請你能解釋我爲什麼該死的上傳界面沒有顯示出來?謝謝!


**編輯3 **

非常感謝您約翰尼,我是不知道的事實,jQuery和原型不能住在一起。 現在該插件顯示正確,但作爲嘗試上傳的東西,它會創建一個新的「上傳」記錄,但其附件字段爲空,且文件不在s3上。

這就是控制檯說:

Started POST "/uploads" for 127.0.0.1 at 2011-06-27 16:17:22 +0200 
    Processing by UploadsController#create as JSON 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"GesRBTiZR1f2LV/bAeAdxWqF++gxcDJw4pPGStYGsH8=", "upload"=>{"attachment"=>[#<ActionDispatch::Http::UploadedFile:0x000001032834b8 @original_filename="animal-tiger-66550.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"upload[attachment][]\"; filename=\"animal-tiger-66550.jpg\"\r\nContent-Type: image/jpeg\r\n", @tempfile=#<File:/var/folders/Qj/QjEqvUUNGTmuki5SXOaaG++++TI/-Tmp-/RackMultipart20110627-1818-1syiex9>>]}} 
    AREL (0.5ms) INSERT INTO "uploads" ("attachment", "created_at", "updated_at", "attachment_file_name", "attachment_content_type", "attachment_file_size", "attachment_updated_at") VALUES (NULL, '2011-06-27 14:17:23.049136', '2011-06-27 14:17:23.049136', NULL, NULL, NULL, NULL) 
[paperclip] Saving attachments. 
Completed 200 OK in 64ms (Views: 4.2ms | ActiveRecord: 0.7ms) 

回答

5

你可以看看jQuery-File-Upload。演示here和導軌3 /回形針設置here

編輯:作爲@apneadiving提到,該庫已更新到版本5.您有腳本是verison 4.你應該試着修改this用回形針工作。複製 - 粘貼大部分示例代碼到我的應用程序(有一些修改)工作對我來說:


#app/public/javascripts/application.js 
$(function() { 
    // Initialize the jQuery File Upload widget: 
    $('#fileupload').fileupload(); 

    // Load existing files: 
    $.getJSON($('#fileupload form').prop('action'), function (files) { 
    var fu = $('#fileupload').data('fileupload'); 
    fu._adjustMaxNumberOfFiles(-files.length); 
    fu._renderDownload(files) 
     .appendTo($('#fileupload .files')) 
     .fadeIn(function() { 
      // Fix for IE7 and lower: 
      $(this).show(); 
     }); 
    }); 

    // Open download dialogs via iframes, 
    // to prevent aborting current uploads: 
    $('#fileupload .files a:not([target^=_blank])').live('click', function (e) { 
     e.preventDefault(); 
     $('<iframe style="display:none;"></iframe>') 
     .prop('src', this.href) 
     .appendTo('body'); 
    }); 

}); 

#app/controllers/uploads_controller.rb 
def create 
    @upload = Upload.new(params[:upload]) 
    if @upload.save 
    render :json => [{ 
       :pic_path => @upload.attachment.url.to_s , 
       :name => @upload.attachment.instance.attributes["picture_file_name"] 
      }], :content_type => 'text/html' 
    else 
    render [:json => { :result => 'error'}], :content_type => 'text/html' 
    end 
end 

#app/views/uploads/new.html.haml 
    %link#theme{:href => "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/themes/base/jquery-ui.css", :rel => "stylesheet"} 
    = stylesheet_link_tag 'jquery.fileupload-ui' 
    #fileupload 
     = form_for Upload.new, :html => { :multipart => true } do |f| 
     .fileupload-buttonbar 
      %label.fileinput-button 
      %span Add files... 
      = f.file_field :attachment, :multiple => true 
      %button.start{:type => "submit"} Start upload 
      %button.cancel{:type => "reset"} Cancel upload 
      %button.delete{:type => "button"} Delete files 
     .fileupload-content 
     %table.files 
     .fileupload-progressbar 
    %script#template-upload{:type => "text/x-jquery-tmpl"} 
     %tr{:class => "template-upload{{if error}} ui-state-error{{/if}}"} 
     %td.preview 
     %td.name ${name} 
     %td.size ${sizef} 
     {{if error}} 
     %td.error{:colspan => "2"} 
      Error: 
      {{if error === 'custom_failure'}}Custom Error Message 
      {{else}}${error} 
      {{/if}} 
     {{else}} 
     %td.progress 
      %div 
     %td.start 
      %button Start 
     {{/if}} 
     %td.cancel 
      %button Cancel 
    %script#template-download{:type => "text/x-jquery-tmpl"} 
     %tr{:class => "template-download{{if error}} ui-state-error{{/if}}"} 
     {{if error}} 
     %td 
     %td.name ${name} 
     %td.size ${sizef} 
     %td.error{:colspan => "2"} 
      Error: 
      {{if error === 1}}File exceeds upload_max_filesize (php.ini directive) 
      {{else}}${error} 
      {{/if}} 
     {{else}} 
     %td.preview 
      {{if thumbnail_url}} 
      %a{:href => "${url}", :target => "_blank"} 
      %img{:src => "${thumbnail_url}"}/ 
      {{/if}} 
     %td.name 
      <a href="${url}"{{if thumbnail_url}} target="_blank"{{/if}}>${name} 
     %td.size ${sizef} 
     %td{:colspan => "2"} 
     {{/if}} 
     %td.delete 
      %button{"data-type" => "${delete_type}", "data-url" => "${delete_url}"} Delete 

編輯 了快速看看你的應用程序,問題是你正在與jquery混合原型。最簡單的方法是使用jquery-rails切換到jQuery。

#Gemfile 
gem 'jquery-rails' 

接下來,運行bundle install,然後運行rails g jquery:install

然後改變你的app/views/layouts/application.erb這樣:

<%= stylesheet_link_tag :all %> 
<%= csrf_meta_tag %> 

<%= javascript_include_tag 'jquery.min' %> 
<%= javascript_include_tag 'jquery-ui-1.8.13.custom.min' %> 
<%= javascript_include_tag 'jquery.tmpl.min' %> 
<%= javascript_include_tag 'jquery.iframe-transport' %> 
<%= javascript_include_tag 'jquery.fileupload' %> 
<%= javascript_include_tag 'jquery.fileupload-ui' %> 
<%= javascript_include_tag 'jquery_ujs' %> 
<%= javascript_include_tag 'application' %> 

注意,我刪除了

<%= javascript_include_tag :defaults %> 

這樣我可以指定了jQuery,jquery_ujs和應用程序加載的順序。

+0

@Johnny Grass:的確,jQuery File Upload現在是v5,我在這裏做了一個新的教程:https://github.com/blueimp/jQuery-文件上傳/ wiki/Rails-setup-for-V5 – apneadiving

+0

它不工作...上傳插件沒有顯示出來。我確定我已經正確加載了所有.js文件,因爲我檢查了safari的java控制檯。你確定這個解決方案適合你嗎? – Abramodj

+0

是的,我上面貼出來的作品適合我。確保你有最新版本的jQuery和jQuery UI。 – David

1

最近我開始了一個非常類似的任務,swf plugin(至少是最近的一個)確實會讓你更新回形針的記錄。它有幾乎所有你需要擴展的回調。

:onUploadComplete (upload_options,event) 

這裏是關於此事的Nathan Colgate的gist。上傳完成後,他只需向Rails服務器進行遠程調用,告訴它回形針附件的位置。

從他uploadCompleteHandler

var uploadCompleteHandler = function(upload_options,event){ 
$.ajax({ 
     url: '<%= notify_rails_of_successful_upload_path(:format => :js)%>', 
     global: false, 
     type: 'POST', 
     data: ({ 
     'authenticity_token' : '<%= form_authenticity_token %>', 
    'upload' : { 
     'file_file_name' : upload_options.FileName, 
      'file_file_size' : upload_options.FileSize, 
      'file_content_type' : upload_options.ContentType 
    } 
    }), 
     dataType: 'script' 
    } 
) 
}; 

我不知道這是否確切的回調被觸發爲每個文件;它絕對看起來像它會。但他通過ajax請求傳回所有回形針需要的東西。文件名,大小,內容類型。通過這種方式,所有發送給heroku的文件都是關於該文件的一些文本,通過將該文件提供給客戶端來節省您的應用程序的大量工作量。

編輯:閃光燈是我發現避免通過heroku發送大量數據到s3的唯一途徑。有幾個html5/js只能上傳,可能能夠完成這項工作,但我發現的那些在開發樹上還是相當成熟的。

+0

我已經實現了這個,遵循Vimeo的教程,但是我得到這個錯誤:NoMethodError(未定義的方法'&'for「v」:String): app/controllers/s3_uploads_controller.rb:36:在'index' – Abramodj

0

查看:(注意陣列blog_post[avatars][]

<form accept-charset="UTF-8" action="/blog_posts" enctype="multipart/form-data" id="new_blog_post" method="post"> 
<div style="margin:0;padding:0;display:inline"> 
<input name="utf8" type="hidden" value="&#x2713;" /> 
<input name="authenticity_token" type="hidden" value="<%=form_authenticity_token %>" /> 
</div> 
<p><input id="blog_post" name="blog_post[avatars][]" type="file" multiple /></p> 
<p><input name="commit" type="submit" value="Upload" /></p> 
</form> 

控制器:

# POST /blog_posts 
# POST /blog_posts.json 
def create 

    @blog_post = BlogPost.new(params[:blog_post]) 

    @blog_post.avatars.each do |avatar| 

     each_blog_post = BlogPost.new 

     each_blog_post.avatar = avatar 

     if each_blog_post.save 

     end 

    end 

end 

型號:

class BlogPost < ActiveRecord::Base 

    attr_accessible :title, :avatar, :avatars 

    has_attached_file :avatar 

    attr_accessor :avatars 

end