【问题标题】:Carrierwave and Dropzone with Nested Attributes具有嵌套属性的 Carrierwave 和 Dropzone
【发布时间】:2016-01-06 09:57:21
【问题描述】:

我整天都在与这个问题作斗争,似乎无法找到解决方案。

在我的应用程序中,用户可以创建一个属性并为该属性上传许多照片,由这些模型定义:

Property.rb:

class Property < ActiveRecord::Base
   belongs_to :user

   has_many :attachments, dependent: :destroy
   accepts_nested_attributes_for :attachments, allow_destroy: true
end

附件.rb:

class Attachment < ActiveRecord::Base        
    mount_uploader :photo, PhotoUploader
    validates_presence_of :photo

    belongs_to :property        
end

如您所见,Attachment 使用 Carrierwave 上传器上传图片。

这是我的控制器中定义的create方法,很简单:

properties_controller.rb

def create
    @property = current_user.properties.build(property_params)

    if @property.save
        save_photos
        flash[:notice] = "Your property has been created."
        redirect_to @property
    else 
        flash[:alert] = "Something went wrong."
        render :new
    end
end

这些是强参数和保存照片的方法:

def property_params
   params.require(:property).permit(:name, :price, :address, :department, :type_id, :description, attachment_attributes: [:id, :property_id, :photo])
end

def save_photos
   # Create Each Uploaded Photo
   params[:attachments]['photo'].each do |photo|
      @attachments = @property.attachments.create!(:photo => photo)
   end
end

到目前为止,文件上传的工作方式与此类似,无需使用 Dropzone。但是,当我想将 Dropzone 集成到我的表单中时,问题就出现了。

我已将 dropzone 类添加到我的表单中,从视图中:

_form.html.haml

= f.fields_for :attachments do |at|
   = f.file_field :photo, :multiple => true, name: "attachments[photo][]"

现在,在我的 dropzone 配置文件中:

properties.js

$(document).ready(function(){
  // disable auto discover
  Dropzone.autoDiscover = false;

  // grap our upload form by its id
  $("#new_property").dropzone({
    // restrict image size to a maximum 1MB
    maxFilesize: 5,

    // changed the passed param to one accepted by our rails app
    paramName: "attachments[photo]",

    // show remove links on each image upload
    addRemoveLinks: true,
    dictDefaultMessage: "Arrastre sus fotos aqui.",
    autoProcessQueue: false,
    uploadMultiple: true,
    parallelUploads: 5,
    maxFiles: 5,


     // The setting up of the dropzone
    init: function() {
      var myDropzone = this;

      // First change the button to actually tell Dropzone to process the queue.
      this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
        // Make sure that the form isn't actually being sent.
        e.preventDefault();
        e.stopPropagation();
        myDropzone.processQueue();
      });

      // Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead
      // of the sending event because uploadMultiple is set to true.
      this.on("sendingmultiple", function() {
        // Gets triggered when the form is actually being sent.
        // Hide the success button or the complete form.
      });
      this.on("successmultiple", function(files, response) {
        // Gets triggered when the files have successfully been sent.
        // Redirect user or notify of success.
      });
      this.on("errormultiple", function(files, response) {
        // Gets triggered when there was an error sending the files.
        // Maybe show form again, and notify user of error
      });
  }




  });
});

此代码包含使用表单的配置,只有在提交整个表单时才会上传照片,如this tutorial 中所述。

所以一旦实现了 dropzone,我就可以毫无问题地删除文件。但是,当我尝试上传表单时,它似乎无法识别照片文件参数。我收到以下错误:

PropertiesController#create undefined method `[]' 中的 NoMethodError 对于零:NilClass 在线:params[:attachments]['photo'].each do |照片|

似乎只要我添加了 dropzone,参数就会消失并变为 nil。我曾尝试在 dropzone 配置中玩弄 nameParam 属性,但都无济于事。

非常感谢您的帮助...

【问题讨论】:

  • 是的 nameParam 消失了,无论我改变什么,我都看不到效果。我得到的只是原始的 nameParam 文件
  • 你解决了这个@Andres

标签: ruby-on-rails file-upload carrierwave nested-attributes dropzone.js


【解决方案1】:

Erm.. 我知道已经晚了,但我有一个答案。

您的表单名称是attachments[photo][] 对吗?

您的放置区应如下所示:

paramName: attachments[photo]
uploadMultiple: true

解决方案在这里:

def save_photos
   # Create Each Uploaded Photo
   params[:attachments]['photo'].each do |photo|
      @attachments = @property.attachments.create!(:photo => photo.pop)
   end
end

您只需要弹出包含文件的最后一个数组值。由于在 dropzone 中,当您添加 uploadMultiple: true 时,输出将是 [0, file1], [1, file2] and etc. 所以 photo.pop 将得到 [file1] [file2] etc. 并推送到数据库。

【讨论】:

  • Hello Kris,但是方法 pop 删除了数组中的最后一个元素并返回它。所做的是保存文件照片。没有?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-25
  • 1970-01-01
  • 1970-01-01
  • 2016-02-03
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多