添加了图像上传进度条(Paperclip、Javascript),但图像本身没有被保存。我怎样才能解决这个问题?

Posted

技术标签:

【中文标题】添加了图像上传进度条(Paperclip、Javascript),但图像本身没有被保存。我怎样才能解决这个问题?【英文标题】:Added a image upload progress bar (Paperclip, Javascript), but images themselves are not being saved. How can I fix this? 【发布时间】:2019-07-12 10:29:02 【问题描述】:

更新五

我刚刚做了一个调试器,这是日志(箭头出现在第 61 行),所以看起来产品项会失败。

   47:  def create
   48:    @product = Product.new(product_params)
   49:
   50:    respond_to do |format|
   51:      if @product.save
   52:
   53:        if params[:images]
   54:          params[:images].each  |image|
   55:            @product.pictures.create(image: image)
   56:          
   57:        end
   58:        flash[:notice] = "The product was successfully added."
   59:        redirect_to show_product_path and return
   60:      else
=> 61:        flash[:notice] = "The product was not able to be saved."
   62:        redirect_to new_product_path and return
   63:      end
   64:    end
   65:  end

更新四

抱歉,在之前的更新中,我在 Product 控制器中遗漏了一些东西,只是重定向命令。

  def create
    @product = Product.new(product_params)

    respond_to do |format|
      if @product.save

        if params[:images]
          params[:images].each  |image|
            @product.pictures.create(image: image)
          
        end
        flash[:notice] = "The product was successfully added."
        redirect_to show_product_path and return
      else
        flash[:notice] = "The product was not able to be saved."
        redirect_to new_product_path and return
      end
    end
  end

更新三

我刚刚意识到,因为我删除了一些代码,我可能遗漏了一些重要的东西。我确实有一个用户模型,即:

class User < ActiveRecord::Base
    has_many :products, :dependent => :destroy
end

从本质上讲,用户创建了一个产品,产品本身通过图片模型与它相关联的图像。我希望这能更清楚地解释事情。

更新两次

我仍然收到与上述相同的错误,但我已将模型更新如下:

(将用户改成用户,忘记添加foreign_key,可选:true不起作用,错误是这是未知键)

class Product < ActiveRecord::Base
  belongs_to :user, :foreign_key => 'user_id', optional: true
  has_many :pictures, :dependent => :destroy
end


class Picture < ActiveRecord::Base
  belongs_to :product, optional: true
  has_attached_file :image,
    :path => ":rails_root/public/images/:id/:filename",
    :url  => "/images/:id/:filename"

  do_not_validate_attachment_file_type :image
end

更新一个

这是我上传图片时的日志:

Started POST "/products" for [IP ADDRESS] at [DATE AND TIME]
Processing by ProductsController#create as */*
  Parameters: "file"=>#<ActionDispatch::Http::UploadedFile:0x007f621971b808 @tempfile=#<Tempfile:/tmp/RackMultipart20190227-181-kldesh.JPG>,     @original_filename="book1.JPG", @content_type="image/jpeg",     @headers="Content-Disposition: form-data; name=\"file\";     filename=\"book1.JPG\"\r\nContent-Type: image/jpeg\r\n">, "product"=>    "name"=>"test"
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 21]]
   (0.2ms)  BEGIN
   (0.2ms)  ROLLBACK
Redirected to http://localhost:3000/products/new
Completed 200 OK in 7ms (ActiveRecord: 0.7ms)

本质上,图像无法保存,它正在重定向回产品新页面。我不知道为什么会这样。

原始问题

所以我有一个使用 Paperclip 的基本图像上传系统(它允许上传多个图像,并且它们与创建的每个产品相关联)。我现在的问题是尝试添加图片上传进度条,在四处搜索之后,听起来 Jquery 最适合这个。

我一直在关注这个:https://github.com/hayageek/jquery-upload-file,但我无法让它工作。

所以我有“产品”,它本身链接到“图片”。产品与图片是一对多的关系。

架构:

  create_table "products", force: :cascade do |t|
    t.string   "name"
    t.string   "description"
    t.integer  "image"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "user_id"
  end

  create_table "pictures", force: :cascade do |t|
    t.string   "description"
    t.string   "image"
    t.integer  "product_id"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "product_token"
    t.string   "image_file_name"
    t.string   "image_content_type"
    t.integer  "image_file_size"
    t.datetime "image_updated_at"
  end

型号:

class Product < ActiveRecord::Base
  belongs_to :users
  has_many :pictures, :dependent => :destroy
end


class Picture < ActiveRecord::Base
  belongs_to :product
  has_attached_file :image,
    :path => ":rails_root/public/images/:id/:filename",
    :url  => "/images/:id/:filename"

  do_not_validate_attachment_file_type :image
end

控制器(产品):

(我故意遗漏了一些东西,但我认为主要是创建操作)

  def create
    @product = Product.new(product_params)

    respond_to do |format|
      if @product.save

        if params[:images]
          params[:images].each  |image|
            @product.pictures.create(image: image)
          
        end
        flash[:notice] = "The product was successfully added."
        format.html  redirect_to @product, notice: 'Product was successfully created.' 
        format.json  render json: @product, status: :created, location: @product 
      else
        flash[:notice] = "The product was not able to be saved."
        format.html  render action: "new" 
        format.json  render json: @product.errors, status: :unprocessable_entity 
      end
    end
  end

查看(针对新产品)(再次,我删除代码只是为了显示最相关的内容):

<%= form_for @product, :html =>  :class => 'form-horizontal', multipart: true  do |f| %>
  <div class="control-group">
    <%= f.label :name, :class => 'control-label' %>
    <div class="controls">
      <%= f.text_field :name, :class => 'text_field' %>
    </div>
  </div>

  <div class="control-group">
    <%= f.label :description, :class => 'control-label' %>
    <div class="controls">
      <%= f.text_field :description, :class => 'text_field' %>
    </div>
  </div>

  <div class="control-group">
    <%= f.label :pictures, :class => 'control-label' %>
    <div class="controls">
      <%= file_field_tag "images[]", type: :file, multiple: true %>
    </div>
  </div>

  <div class="form-actions">
    <%= f.submit nil, :class => 'btn btn-primary' %>
  </div>
<% end %>

显示(针对产品):

        <td> Name </td>
        <td> <%= @product.name %> </td>
    <div class = "images_styling"> Photos </div>
    <% @products.pictures.each do |picture| %>
    <%= image_tag picture.images.url(:medium) %>
    <% end %>

现在这是我尝试做的:

(添加了文件上传id,提交时添加了保存id)

查看新产品表单

  <div class="control-group">
    <%= f.label :pictures, :class => 'control-label' %>
    <div class="controls" id="fileUpload" >
      <%= file_field_tag "images[]", type: :file, multiple: true %>
    </div>
  </div>

  <div id="save" class="form-actions">
    <%= f.submit nil, :class => 'btn btn-primary' %>
  </div>

这是我在网上获得的脚本(在新产品视图中显示):

<script type="text/javascript">
  $(document).ready(function () 

      var fileUpload = $("#fileUpload").uploadFile(
      url: "/products",
      multiple: true,
      autoSubmit: false,
      showCancel: false,
      showAbort: false,
      dragDrop: true,
      maxFileCount: 4,
      showPreview: true,
      showProgress: true,
      showStatusAfterSuccess: true,
      dynamicFormData: function () 
        var name = $('#product_name').val();
        var data = "product[name]": name;
        return data;
      
    );

    $("#save").click(function (e) 
      $("#save").prop("disabled", true);
      fileUpload.startUpload();
      e.preventDefault();
    );


  );

</script>

但它不起作用。相反,当我单击提交按钮时,它会“开始”然后“回滚”。有趣的是,该按钮确实显示了每张图片的上传进度条。

但是,当我查看产品的“展示”时,图像并不存在。我猜由于“回滚”,图像没有保存到产品中。我查看了日志,其中似乎没有任何实质性内容。

基于此,我该怎么做才能让它发挥作用?有没有更简单的方法来实现我想做的事情?

【问题讨论】:

你有控制台日志输出吗? 嗨 cd-rum,我刚刚添加了它。 你运行的是什么版本的 Rails?尝试将optional: true 添加到您的关系中。 另外,belongs_to :users(即复数而不是user)似乎是个错误? 【参考方案1】:

Rails 5+ 使所有belongs_to 关系required by default。通过在表单或控制器或模型中设置:user:product 来解决您的问题,或者同时设置optional: true

您也不能拥有belongs_to :users(即,不属于多人)。

【讨论】:

嗨 cd-rum。谢谢回复。这很奇怪,我做了以下事情: Product model belongs_to :user 关于可选:true,我意识到我忘记为 Product 模型添加 foreign_key (因为我确保删除某些代码,并错过了这个)所以应该是:belongs_to :user, :foreign_key =&gt; 'user_id' 如果我添加 optional: true,它不起作用,因为它声明它是一个“未知密钥”,但我可以将 optional: true 添加到产品中。【参考方案2】:

按照日志,在ProductsController#createif @product.save 行执行永远不会成功。

使用记录器或调试器,您能否判断执行是否进入了操作?

在该控制器或重定向到/products/new 的任何超类(包括mixin)中是否有任何before_actionaround_action


啊,所以@product.save 失败了。改成@product.save!,会引发异常而不是返回“success false”,看看引发的异常是什么。

【讨论】:

您好,Kache,感谢您的回复。我意识到我为 Products 控制器遗漏了一些代码(因为我试图使其尽可能简洁),但是重定向到 products/new 是如果 Products create 方法失败。关于您的问题,我已经查看了控制器中没有任何 before_action 或 around_action 。如果您需要更多信息,请告诉我。 抱歉,我跳过了你的第一个问题。我实际上是初级 RoR 开发人员,所以我以前没有使用过记录器/调试器。我会试试看我能做些什么 嗨,Kache,所以我现在刚刚做了调试器,我已经更新了问题(因为它有点太长了,不能作为评论) 嗨@JamesWu,我刚刚更新了,你能再检查一下吗?如果有帮助,我的回答能被接受就太好了。 嗨,Kache,抱歉,因为我现在才这样做。烦人的是,我现在要把它放在次要位置,因为让它发挥作用是一次非常令人沮丧的经历。不过,我已经给你加分了。

以上是关于添加了图像上传进度条(Paperclip、Javascript),但图像本身没有被保存。我怎样才能解决这个问题?的主要内容,如果未能解决你的问题,请参考以下文章

快速在 UICollectionView 中显示多个图像上传的进度条

java上传Excel文件,如何实现进度条显示?

如何使用Paperclip在Rails 4中上传多个图像

将图像上传到 Firebase 存储时如何制作进度条?

上传图片 - Nodejs Paperclip 和 S3

Paperclip + Rails 与负载平衡机器