我最近花了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 %>
提前感谢您的任何回复!
答案 0 :(得分:0)
老实说,我不完全确定我是否理解你的问题,但是response_to format.js可能没有按照你的想法行事。 Check out this answer to a related question.