Rails 4,Ajax,jQuery。 Form_for with remote:true不作为js发送

时间:2014-11-26 00:35:33

标签: jquery ruby-on-rails ajax

我最近花了2天时间挖掘Google和SO。没什么...

我想做的事情很简单。

我有2个型号:产品和供应商。在产品创建表单上,我有字段将其分配给现有供应商。并且还有链接'创建新供应商'如果供应商不在列表中。

点击此链接会显示新供应商的表单(它向供应商#new发出请求并呈现新的供应商表单),但是当点击提交时,表单将作为http post请求正常发送到SuppliersController #create。它应该通过Ajax发送,因此我可以将js(从Supplier create method中的respond_to ... format.js)返回到Products create form。相反,它会重定向到供应商控制器中的供应商页面。

这是SO上的类似问题:

processing controller actions as JS instead of HTML

我知道它应该是JS。我还根据动作名称完成了js.erb文件。

这是我的产品控制器:

class ProductsController < ApplicationController
      before_action :set_product, only: [:show, :edit, :update, :destroy]

      # GET /products
      # GET /products.json
      def index
        @products = Product.includes(:product_suppliers).order('name').order('product_suppliers.price_product_supplier DESC')


      end

      # GET /products/1
      # GET /products/1.json
      def show
      end

      # GET /products/new
      def new
        @product = Product.new
        @product.product_suppliers.new

      end

      # GET /products/1/edit
      def edit
      end

      # POST /products
      # POST /products.json
      def create
        @product = Product.new(product_params)
    #    @product.product_suppliers.find_by_product_id(@product.id).update_attributes(price_product_supplier: params[:price])

        respond_to do |format|
          if @product.save
            format.html { redirect_to @product, notice: 'Product was successfully created.' }
            format.js
          else
            format.html { render :new }
            format.js
          end
        end

      end

      # PATCH/PUT /products/1
      # PATCH/PUT /products/1.json
      def update
        respond_to do |format|
          if @product.update(product_params)
            format.html { redirect_to @product, notice: 'Product was successfully updated.' }
            format.js
          else
            format.html { render :edit }
            format.js
          end
        end
      end

      # DELETE /products/1
      # DELETE /products/1.json
      def destroy
        @product.destroy
        respond_to do |format|
          format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
          format.js
        end
      end

      private
        # Use callbacks to share common setup or constraints between actions.
        def set_product
          @product = Product.find(params[:id])
          if @product.product_suppliers.exists?
            return true
          else
            @product.product_suppliers.new
          end
        end

        # Never trust parameters from the scary internet, only allow the white list through.
        def product_params
          params.require(:product).permit(:name, :description, product_suppliers_attributes: [:id, :supplier_id, :project_id, :price_product_supplier, :_destroy])
        end
    end

其形式部分(product_supplier是产品和供应商之间具有hmt关系的连接模型:

= form_for @product do |f|
      - if @product.errors.any?
        #error_explanation
          %h2
            = pluralize(@product.errors.count, "error")
            prohibited this product from being saved:
          %ul
            - @product.errors.full_messages.each do |message|
              %li= message

      .field
        = f.label :name
        %br/
        = f.text_field :name

      .field
        = f.label :description
        %br/
        = f.text_area :description

      .product-suppliers
        = f.nested_fields_for :product_suppliers, wrapper_tag: :div, wrapper_options: { class: "row" } do |ps|
          = ps.label :name
          = ps.collection_select :supplier_id, Supplier.all, :id, :name, prompt: true
          = ps.label :price_product_supplier
          = ps.text_field :price_product_supplier
          = ps.remove_nested_fields_link
        = f.add_nested_fields_link :product_suppliers, "Match another supplier"
        or 
        = link_to "Create new supplier", new_supplier_path, id: "supplier_new", remote: true         

      .field
        .actions
          = f.submit 'Save'

供应商控制器看起来像脚手架之后,而是format.json,有没有attrs的format.js。供应商表格:

<%= form_for @supplier, remote: true, authenticity_token: true  do |f| %>
  <% if @supplier.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@supplier.errors.count, "error") %> prohibited this supplier from being saved:</h2>

      <ul>
      <% @supplier.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :address %><br>
    <%= f.text_field :address %>
  </div>
  <div class="field">
    <%= f.label :telno %><br>
    <%= f.text_field :telno %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

提前感谢您的任何回复!

1 个答案:

答案 0 :(得分:0)

老实说,我不完全确定我是否理解你的问题,但是response_to format.js可能没有按照你的想法行事。 Check out this answer to a related question.