Rails 3 and a Nested jQuery File Upload Model

2019-03-22 05:00发布

Does anyone have advice/examples on getting the jQuery File Upload plugin working with Rails using nested attributes?

My model "has_many" attachments and accept the necessary nested attributes. I would like to get this working with the jQuery File Upload but haven't been able to find any good examples to get me started.

Has anyone achieved something like this and able to give some direction?

Thanks.

4条回答
劫难
2楼-- · 2019-03-22 05:39

I have coped with this problem and made a demo app to show how to do this.

In short I have two models: item and upload.

item.rb:

has_many :uploads
accepts_nested_attributes_for :uploads, :allow_destroy => true

upload.rb:

belongs_to :item
    has_attached_file :upload, :styles => { :large => "800x800", :medium => "400x400>", :small => "200x200>" }

I added uploads_attributes to item controller.

Now you can add jquery-file-upload form to your view, but there is one problem: it sends each photo in separate requests. So there is my jquery-file-upload initializer, which uploads all photos in one request (creating item model) and then redirecting to the root of your app (you need to use item form):

<script type="text/javascript" charset="utf-8">
    var num_added = 0;
    var added = 0;
    var all_data = {};
    $(function () {
        // Initialize the jQuery File Upload widget:
        $('#fileupload').fileupload({
          complete: function (e, data) {
            window.location = "<%= root_url %>";
        },
          singleFileUploads: false
        })  .bind('fileuploadadd', function (e, data) {num_added++;})
            .bind('fileuploadsubmit', function (e, data) {
            if(added < num_added)
            {
            if (added == 0)
            all_data = data;
            else
            {
            $.each(data['files'], function(i, file){
            all_data['files'].push(file);
            });
            $.each(data['context'], function(i, context){
            all_data['context'].push(context);
            });
            }
            added++;
            if (added == num_added)
            {
            added++;
            all_data.submit();
            }
            return false;
            }
            })
            .bind('fileuploadsend', function (e, data) {num_added = 0; added = 0;});

        // 
        // Load existing files:
        $.getJSON($('#fileupload').prop('action'), function (files) {
          var fu = $('#fileupload').data('blueimpFileupload'), 
            template;
          fu._adjustMaxNumberOfFiles(-files.length);
          console.log(files);
          template = fu._renderDownload(files)
            .appendTo($('#fileupload .files'));
          // Force reflow:
          fu._reflow = fu._transition && template.length &&
            template[0].offsetWidth;
          template.addClass('in');
          $('#loading').remove();
        });

    });
  </script>
查看更多
beautiful°
3楼-- · 2019-03-22 05:40

Take a look at the 7 minute mark of this video. http://ror-e.com/info/videos/3

It describes a way to upload images "product has_many images" You should look at the ror_ecommerce source and in admin/merchandise/images/products you can look at the code.

https://github.com/drhenner/ror_ecommerce

The JS is in application.js and the application_helper.rb

查看更多
萌系小妹纸
4楼-- · 2019-03-22 05:44

I spent a long time getting it to work in a project of mine. Here's a link to a giant SO post I made on a different question. It may help you.

Rails 3 + JQuery-File-Upload + Nested Model

查看更多
放荡不羁爱自由
5楼-- · 2019-03-22 06:03

I've succesfuly set it up to work when editing a model with nested attachments.
The same is not possible when creating a new model - at least not currently due to paperclip.

You have to set up some jQuery File Upload options which I found here.

You should call fileUploadUI() on the whole form, and set file input wrapper element as dropZone. You should also set url, fieldName and formData accordingly.

Here's how my JS looks like (simplified):

var $file_upload_form = $("form")
var attachable_id     = $file_upload_form.attr("id").match(/_(\d*)$/)[1]
var attachable_type   = $file_upload_form.attr("id").match(/edit_(\w*)_\d*$/)[1]

$($file_upload_form).fileUploadUI({
    url         : '/admin/attachments',
    fieldName   : "attachment[data]",
    formData    : [
        {
            name  : 'attachment[attachable_id]',
            value : attachable_id
        },
        {
            name  : 'attachment[attachable_type]',
            value : attachable_type
        }
    ],
    dropZone        : $('#attachments_dropzone'),
    uploadTable     : $('#upload_files'),
    downloadTable   : $('#download_files'),
    buildUploadRow  : function (files, index) {
        var file = files[index];
        return $('<tr><td>' + file.name + '<\/td>' +
                        '<td class="file_upload_progress"><div><\/div><\/td>' +
                        '<td class="file_upload_cancel">' +
                        '<button class="ui-state-default ui-corner-all" title="Cancel">' +
                        '<span class="ui-icon ui-icon-cancel">Cancel<\/span>' +
                        '<\/button><\/td><\/tr>');
    },
    buildDownloadRow: function (file) {
        return $('<tr><td><img alt="Photo" width="40" height="40" src="' + file.pic_path + '">' + file.name + '<\/td><\/tr>');
    }
})
查看更多
登录 后发表回答