jquery-file-upload POST и вложенный маршрут - маршрут не соответствует PATCH

В моем приложении rails4 у меня есть модель Product, в которой много 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>

Мой Javascript

$(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 action:
  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