jquery-file-upload POST และเส้นทางที่ซ้อนกัน - การไม่ได้รับเส้นทางที่ตรงกับ PATCH

ในแอป Rails4 ของฉัน ฉันมีโมเดล ผลิตภัณฑ์ ซึ่งมี ProductImages มากมาย ฉันกำลังพยายามรับการอัปโหลดไฟล์ jquery เพื่อสร้างรูปภาพในรูปแบบพาเรนต์โดยใช้ file_field และฉันได้ตั้งค่าฟิลด์ของฉันให้อัปโหลดอัตโนมัติเมื่อเลือกไฟล์ ฉันมีเพียงวิธีการสร้างและทำลายในตัวควบคุม Product_images ของฉันเท่านั้น

อย่างไรก็ตาม เมื่อพยายามโพสต์ไปที่ URL: "/products/1/product_images" ฉันได้รับข้อผิดพลาดในการกำหนดเส้นทาง

No route matches [PATCH] "/products/1/product_images"

ฉันเห็นในคอนโซลเบราว์เซอร์ว่าวิธีการร้องขอของฉันคือ "POST" แต่แอป Rails พยายามจับคู่เป็น PATCH...

Remote Address:127.0.0.1:80
Request URL:http://appname.dev/products/1/product_images
Request Method:POST
Status Code:404 Not Found

อะไรทำให้แอปใช้ PATCH


Routes.rb

resources :products do
  resources :product_images, only: [:create, :destroy]
end

รูปแบบบางส่วนสำหรับรูปภาพ

<fieldset id="product-images">
    <%= file_field_tag "product_images[]", type: :file, id:"file-select", multiple:true %>
    <% f.fields_for :product_images do |builder| %>
        <%= render "product_images/product_image", f:builder %>
    <% end %>
</fieldset>

จาวาสคริปต์ของฉัน

$(function(){
    /* ---IMAGE AREA--- BEGIN */
    //JQ FILE UPLOAD FUNCTION
    var formURL = $(".edit_product").attr("action") + "/product_images";
    $('#file-select').fileupload({
        url:formURL,
        type:'POST',
        dataType: 'script',
        add: function (e, data) {
            data.context = $('<div class="img uploading"/>').appendTo("#product-images");
            data.submit();
        },
        done: function (e, data) {
            console.log(data.result);
            $.each(data.result.files, function (index, file) {
                console.log(file);
            });
            //$(".no_images").addClass("hidden");
        },
        option: {
                autoUpload: true,
        }
    });
});

ตัวควบคุม

class ProductImagesController < ApplicationController
  before_action :set_product_image, only: [:show, :destroy]

  def show
  end

  def create
    @product = Product.find(params[:product_id])
    @product_image = @product.product_images.create(product_image_params)

    if @product_image.save
      respond_to do |format|
        format.js
      end
    else 
      render :json => [{:error => "custom_failure"}], :status => 304
    end

  end

  def destroy
    @product_image.destroy
    render :json => true
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_product_image
      @product_image = ProductImage.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def product_image_params
      params.require(:product_image).permit(:product_id, :file, :title, :caption)
    end

end

person Joel Grannas    schedule 29.10.2014    source แหล่งที่มา


คำตอบ (1)


เนื่องจากคุณกำลังพยายามสร้าง product_image ในแบบฟอร์มแก้ไขผลิตภัณฑ์ เมื่อปลั๊กอิน JqueryFileUpload ส่งข้อมูลไปยังเซิร์ฟเวอร์ ปลั๊กอินจะส่งข้อมูลแบบฟอร์มทั้งหมด

ตรวจสอบ HTML ที่สร้างขึ้นด้วยเมธอด form_for และค้นหาฟิลด์ที่ซ่อนชื่อเมธอด คุณจะพบว่าค่าคือ patch:

<input name="_method" type="hidden" value="patch">

Rails ใช้สิ่งนี้ พารามิเตอร์เพื่อตรวจสอบว่า POST เป็น PUT, PATCH หรือ DELETE

คุณมีสองทางเลือกในการแก้ปัญหานี้ (ฉันต้องการตัวเลือกแรก):

  1. เพิ่ม patch เส้นทางไปยังไฟล์เส้นทางของคุณ การกำหนดเส้นทางไปยัง product_images#create การกระทำ:
  2. แก้ไขค่า _method ในฟังก์ชันการโทรกลับ formData ของปลั๊กอิน jqueryFileUpload
person Rodrigo    schedule 29.10.2014
comment
ฉันเข้าใกล้สิ่งนี้ผิดหรือเปล่า? ด้วย jquery-file-upload ฉันต้องการเพิ่ม ProductImage ที่เกี่ยวข้องให้กับผลิตภัณฑ์เท่านั้น และไม่จำเป็นต้องอัปเดตบันทึกผลิตภัณฑ์เมื่อเพิ่ม ProductImage ดูเหมือนว่าจะส่งข้อมูลฟอร์มผลิตภัณฑ์ทั้งหมดที่ฉันไม่ต้องการ ฉันเคยทำสิ่งนี้มาแล้วโดยใช้แบบฟอร์มแยกต่างหากในหน้าสำหรับบันทึกการเชื่อมโยง และฟิลด์ product_id ที่ซ่อนอยู่ภายในแบบฟอร์มนี้เพื่อสร้างการเชื่อมโยง แต่ฉันหวังว่าจะเก็บ file_field ไว้ในแบบฟอร์มหลักในอันนี้ - person Joel Grannas; 29.10.2014
comment
ไม่ ค่าเริ่มต้นของ jquery-file-upload คือส่งข้อมูลแบบฟอร์มทั้งหมด หากคุณต้องการแก้ไขข้อมูลที่คุณส่งไปยังเซิร์ฟเวอร์ ให้ใช้ formData ฟังก์ชัน - person Rodrigo; 29.10.2014
comment
ฉันเข้าใจว่าฉันสามารถเขียนทับโดยใช้ formData... แต่ฉันควรโพสต์โดยใช้แบบฟอร์มแยกเฉพาะสำหรับ product_images แทนที่จะใช้แบบฟอร์มผลิตภัณฑ์ที่ซ้อนกันเพื่อสร้างรูปภาพใหม่หรือไม่ นั่นคือวิธีที่ฉันทำในโครงการที่ผ่านมา - person Joel Grannas; 29.10.2014
comment
ได้ จะดียิ่งขึ้นไปอีกหากคุณสามารถใช้แบบฟอร์มพิเศษสำหรับรูปภาพได้ - person Rodrigo; 30.10.2014
comment
บางครั้งเนื่องจากรูปแบบหน้าจอ ฉันจึงไม่สามารถใช้แบบฟอร์มพิเศษได้ ในกรณีเหล่านี้ ฉันใช้วิธีแก้ไขปัญหาแรกที่กล่าวถึงข้างต้น - person Rodrigo; 30.10.2014