【问题标题】:Multiple files upload with Rails 3 and paperclip on heroku使用 Rails 3 和 heroku 上的回形针上传多个文件
【发布时间】:2011-06-26 12:10:25
【问题描述】:

我的 Rails 3 应用程序需要一个界面来将多个文件上传到 Amazon S3(因为我在 heroku 上),可能带有进度条。

我已经轻松掌握了如何设置回形针和上传单个文件,但我现在真的不知道如何继续。

你能给我一些建议吗?我在整个互联网上搜索了 2 天,但我找不到有效的解决方案


** 编辑 **

我真的无法理解...我要疯了,因为我在这方面浪费了太多时间...请帮助我。 如果我尝试打开 Johnny 引用的示例应用程序,我只会得到这个(在我的应用程序中是一样的):

用户界面在哪里? 我的浏览器有问题吗?


** 编辑 2 **

Here on GitHub you can find my testapp... 请你解释一下为什么该死的上传 UI 没有出现?谢谢!


** 编辑 3 **

非常感谢 Johnny,我不知道 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)

【问题讨论】:

    标签: ruby-on-rails paperclip


    【解决方案1】:

    您可以查看 jQuery-File-Upload。演示 here 和 rails 3/Paperclip setup here.

    编辑:正如@a​​pneadiving 提到的,该库已更新到版本5。您拥有的脚本适用于版本4。您应该尝试修改this 以使用PaperClip。将大部分示例代码复制粘贴到我的应用程序中(稍作修改)对我有用:


    #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 和应用程序的加载顺序。

    【讨论】:

    • @Johnny Grass:确实,jQuery File Upload 现在是 v5,我在这里做了一个新的 tut:github.com/blueimp/jQuery-File-Upload/wiki/Rails-setup-for-V5
    • 它不工作...上传插件没有出现。我确定我已经正确加载了所有 .js 文件,因为我已经检查了 safari 的 java 控制台。您确定此解决方案适合您吗?
    • 是的,我在上面发布的内容对我有用。确保您拥有最新版本的 jquery 和 jquery ui。
    • 哦,是的,我确定我两个都有。还有什么可能是我的问题?抱歉,我是这些技术的新手,但我真的很想了解我缺少什么。我会在GitHub上传一个测试项目,有时间可以看看。
    • 我已经编辑了我的问题并插入了我的测试应用程序。请看看它并告诉我我错过了什么
    【解决方案2】:

    我最近开始了一项非常相似的任务,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 的所有内容都是关于文件的一些文本,通过将文件交给客户端,可以为您的应用节省大量工作。

    编辑:flash 是我发现避免通过 heroku 向 s3 发送大量数据的唯一方法。有一些仅支持 html5/js 的上传器可能能够完成工作,但我发现的那些在开发树上仍然非常成熟。

    【讨论】:

    • 我已经按照 Vimeo 上的教程实现了这个,但是我得到了这个错误:NoMethodError (undefined method &amp;' for "v":String): app/controllers/s3_uploads_controller.rb:36:in index'
    【解决方案3】:

    根据Heroku supportsee this

    Paperclip & multiple files upload,虽然不是 S3 特定的。

    【讨论】:

    • SWF 插件不会与回形针对话。并且视频展示了一种使用标准 html 表单的方法,没有任何进度条
    【解决方案4】:

    查看:(注意数组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
    

    【讨论】:

      猜你喜欢
      • 2012-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-13
      • 2012-07-03
      相关资源
      最近更新 更多