使用Dropzone JS的Carrierwave。 是否可以将这些与嵌套属性一起使用?

目前,我有几种使用嵌套属性的表单。 我最近发现了Dropzone JS,所以我希望以我正在使用的各种forms实现它。

我有两个类似的模型:

游戏

class Games < ActiveRecord::base has_many :screenshots, dependent: :destroy accepts_nested_attributes_for :screenshots, allow_destroy: true end 

截图

 class Screenshot < ActiveRecord::Base belongs_to :game mount_uploader :ssfile, ScreenshotUploader end 

通常,我会用这样的东西来处理它:

new.html.haml

 - content_for :breadcrumbs do %h3.text-center New Game .col-md-12#content .row = render 'form' .row .col-md-12 = link_to 'Back', games_path 

_form.html.haml

 .col-md-12 = form_for @game, :html => {:class => 'form-horizontal form-bordered'} do |f| .section-title %h3 General Data .well .form-group =f.label :title, :class => 'col-md-2' .col-md-6 = f.text_field :title, :class => 'form-control' .form-group = f.label :platform, :class => 'col-md-2' .col-md-6 .input-group = f.text_field :platform, :class => 'form-control' .section-title %h3 Screenshots .well#screenshots =f.fields_for :screenshots do |i| =render 'screenshot_fields', :f => i %hr .links =link_to_add_association 'Add Screenshot', f, :screenshots, :class => 'btn btn-default' .row .col-md-12 .actions = f.submit 'Save', :class => 'btn btn-default' 

_screenshot_fields.html.haml

 .form-group -if f.object.ssfile? .col-md-2 =image_tag(f.object.ssfile_url(:thumb)) .col-md-4 %p =f.file_field :ssfile, :class => 'styledfileinput' -if f.object.ssfile? .col-md-2 %p =f.check_box :_destroy =f.label :_destroy, 'Remove' 

这很好用。 当您单击“添加屏幕截图”时,它会加载link_to_add_association助手,该助手是名为Cocoon的gem的一部分。 这个帮助器将创建必要的JS来向表单添加“块”代码,在这种情况下是文件输入,但通常你会有更多其他类型的输入而不是一个。

我想将link_to_add_association添加的块替换为多文件放置区。

我对new.html.haml视图进行了以下更改:

 .col-md-12 = form_for @game, :html => {:class => 'form-horizontal form-bordered', :id => 'gameform'} do |f| -# *snip* .well#screenshots - @game.screenshots.each do |i| =image_tag i.ssfile_url(:thumb) %hr .row .col-md-12 .actions = f.submit 'Save', :class => 'btn btn-default' 

我将#gameform添加到form_for元素中,并替换了显示图片的循环。 到现在为止还挺好。 现在的问题是我不知道文件应该如何与表单交互。

我在加载Dropzone配置的coffeescript上有这个:

 ready = -> if $('#gameform').length > 0 didthiswork = new Dropzone("#gameform", { paramName: "game[screenshot_attributes][ssfile]" }) else console.log('ruh roh') $(document).on('page:load ready', ready) 

现在,我可以点击表格中的任何地方,它会带上传对话框(这本身就是另一个问题),但是一旦我选择了图片,这些图片就没有正确保存。 有没有办法让这个工作与fields_for ? 我有很多其他forms使用非常相似的配置,所以我更喜欢不必更改我的应用程序的整个逻辑(如果可能)。

UPDATE

我想我已经取得了一些进展。 我已经设法让表单发送数据,但是他们没有到达我的预期。

我使用此链接中的信息调整了配置: https : //github.com/enyo/dropzone/wiki/Combine-normal-form-with-Dropzone

在我的coffescript上导致这样的事情:

 Dropzone.options.articuloform = autoProcessQueue: false uploadMultiple: true paramName: "game[screenshot_attributes][ssfile]" parallelUploads: 100 maxFiles: 100 init: -> myDropzone = this # First change the button to actually tell Dropzone to process the queue. @element.querySelector('input[type=submit]').addEventListener 'click', (e) -> # Make sure that the form isn't actually being sent. e.preventDefault() e.stopPropagation() myDropzone.processQueue() return # Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead # of the sending event because uploadMultiple is set to true. @on 'sendingmultiple', -> # Gets triggered when the form is actually being sent. # Hide the success button or the complete form. return @on 'successmultiple', (files, response) -> # Gets triggered when the files have successfully been sent. # Redirect user or notify of success. return @on 'errormultiple', (files, response) -> # Gets triggered when there was an error sending the files. # Maybe show form again, and notify user of error return return 

当我选择图像时(这很棒),这会阻止自动数据上传,但是,一旦按下“提交”按钮,数据就会以错误的结构到达。 他们是在这些来自数据中的:

 Parameters: { "utf8"=>"✓", "authenticity_token"=>"l2siCG2D4xW0eto48WM152MTusc6K5cQYem8K2a9c/Y=", "game"=>{ "title"=>"Super Amazing AAA Title", "platform"=>"Xbox One", "screenshot_attributes"=>{ "ssfile"=>{ "0"=>#<ActionDispatch::Http::UploadedFile:0x000000055c7e98 @tempfile=#, @original_filename="screenshot01.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"game[screenshot_attributes][ssfile][0]\"; filename=\"screenshot01.png\"\r\nContent-Type: image/png\r\n">, "1"=>#<ActionDispatch::Http::UploadedFile:0x000000055c7df8 @tempfile=#, @original_filename="screenshot02.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"game[screenshot_attributes][ssfile][1]\"; filename=\"screenshot02.png\"\r\nContent-Type: image/png\r\n">, "2"=>#<ActionDispatch::Http::UploadedFile:0x000000055c7d30 @tempfile=#, @original_filename="screenshot03.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"game[screenshot_attributes][ssfile][2]\"; filename=\"screenshot03.png\"\r\nContent-Type: image/png\r\n">, "3"=>#<ActionDispatch::Http::UploadedFile:0x000000055c7c90 @tempfile=#, @original_filename="screenshot04.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"game[screenshot_attributes][ssfile][3]\"; filename=\"screenshot04.png\"\r\nContent-Type: image/png\r\n">, "4"=>#<ActionDispatch::Http::UploadedFile:0x000000055c7ba0 @tempfile=#, @original_filename="screenshot05.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"game[screenshot_attributes][ssfile][4]\"; filename=\"screenshot05.png\"\r\nContent-Type: image/png\r\n"> } } }, "null"=>"", "commit"=>"Save", "id"=>"2" } 

重要的部分是每个段的name ,它们是作为game[screenshot_attributes][ssfile][XXXX]到达的,这是错误的,正确的格式应该是game[screenshot_attributes][XXXX][ssfile] 。 我可以在上面粘贴的部分配置它,但重要的部分是paramName部分,我有paramName: "game[screenshot_attributes][ssfile]"

如果有人能有任何线索,我会非常感激。

最后找到了一种方法,使dropzone.js可以使用rails嵌套属性。 您必须编辑dropzone.js以设置多个附件的rails嵌套属性数组的格式。

 Dropzone.prototype._getParamName = function(n) { if (typeof this.options.paramName === "function") { return this.options.paramName(n); } else { return "" + this.options.paramName1 + (this.options.uploadMultiple ? "[" + n + "]" : "") + this.options.paramName2 + ""; } }; 

然后在dropzone初始化javascript初始化两个参数:

 Dropzone.options.newTicket = clickable:'#previews' previewsContainer: "#previews" dictDefaultMessage: "Drop files here or click to select files" autoProcessQueue: false uploadMultiple: true paramName1: "ticket[attachments_attributes]" paramName2: "[file]" parallelUploads: 5 maxFiles: 5 addRemoveLinks: true