如何使用jquery-fileupload嵌套附件?

时间:2013-11-06 12:59:00

标签: jquery ruby-on-rails ruby nested-attributes jquery-file-upload

我正在使用jquery-fileupload-rails来上传多个文件。

我希望能够设置文档名称并向其添加多个附件。

但是现在当我选择3个附件时,它会创建3个documents,每个附件都有一个附件。

我想我需要以某种方式更改添加附件的表单。我添加了多个选项和编码名称。

我想使用这个插件,因为稍后我会想要添加拖放功能。

发件人

= simple_form_for [:member, @document], html: { multipart: true } do |f|
  = f.input :name
  = f.simple_fields_for :attachments, Attachment.new do |a|
    = a.file_field :attachment, multiple: true, name: "document[attachments_attributes][][attachment]"
  = f.submit

生成:

<input id="document_attachments_attributes_0_attachment" multiple="multiple" name="document[attachments_attributes][][attachment]" type="file">

JS

jQuery ->
    $('#new_document').fileupload()

模型

class Document < ActiveRecord::Base
  has_many :attachments
  accepts_nested_attributes_for :attachments
end

class Attachment < ActiveRecord::Base
  belongs_to :document

  has_attached_file :attachment
end

控制器

class Member::DocumentsController < ApplicationController
  def new
    @document = Document.new
  end

  def create
    @document = Document.new params[:document]

    if @document.save
      redirect_to member_documents_path, notice: "Created"
    else
      redirect_to member_documents_path, alert: "Not created"
    end
  end

  private

  def document_params
    params.require(:document).permit(:name, attachments_attributes: [:attachment])
  end
end

1 个答案:

答案 0 :(得分:3)

我用两种不同的形式做了类似的事情。基本上,您为具有名称字段和attachment_ids的隐藏字段的文档创建表单,然后为附件创建表单。您可以单独上传附件(不幸的是,它们当时是孤立的记录),然后使用新创建的附件记录的ID更新文档下的隐藏字段。

所以基本上,从附件控制器创建一个json响应,包括新创建的对象的id。然后创建一个javascript函数,将每个成功回调中新创建的ID添加到隐藏字段。

我确信有一种更简单的方法可以做到这一点,但我总是被多文件上传和嵌套属性所困扰。

编辑:所以我找到了一些旧代码并将其移植过来。

class Member::AttachmentsController < Member::BaseController

  def create
    @attachment = Attachment.create!(params[:attachment])
    # TWO APPROACHES, render json view, or respond with a .js view create.js.erb
    # render json: @attachment.to_json

  end

end

class Member::DocumentsController < Member::BaseController

  def create
    @document = Document.new params[:document]
    @attachments = Attachment.find(params[:attachment_ids].split(','))
    if @document.save
      @document.attachments = @attachments
      redirect_to member_documents_path, notice: "Created"
    else
      redirect_to member_documents_path, alert: "Not created"
    end
  end
end

然后你要么在截图中创建一个create.js.erb

var screenshotContainer, 
    idContainer;

screenshotContainer = $('#attachments');
idContainer =  $('#attachment_ids_hidden_field');  

screenshotContainer.append('<%= j render @attachment %>');

idContainer.val(function(i, v) {
  var arr = v.split(', ');
  arr.push('<%= @attachment.id %>');
  return arr.join(', ');
});

例如,这可能是一个屏幕截图渲染调用,但是您可以在部分中显示它。

<%= image_tag(attachment.attachment, size: "100x100", data: { attachment_id:     attachment.id }) if attachment.attachment? %>

在文件表格中创建

<input type="hidden" id="attachment_ids_hidden_field" value="" name="attachment_ids">

另一种方法是使用json进行响应,并在fileupload的完成回调中将新附件的json ID添加到隐藏字段。

你需要解析hidden_​​ids的任何乱七八糟的东西,而不仅仅是.split(',')

我没有机会仔细研究这个问题。

希望它有所帮助。