通过 ajax Rails 4 构建的表单将子项添加到父项
Add children to parent from form constructed via ajax Rails 4
我有以下表格:
当用户从下拉列表中选择产品时,将触发 ajax 以查找单个产品的库存以将详细信息附加到 table。
用户可以在订单中附加产品详细信息。
最后我得到了类似的东西:
{"utf8"=>"✓", "authenticity_token"=>"xmlzMouWp0QGUnpKeawQ8OCPJ/GlF2bp0kn97ra2Qyb7TgsCkXmJEGD1l/oZitn+VPVJRc8x79/kTUtgbbDr0A==", "order"=>{"customer_search"=>"", "customer_id"=>"2", "product_search"=>"", "order_detail"=>[{"product_id"=>"10", "product_detail_id"=>"13", "price_id"=>"12"}, {"product_id"=>"1", "product_detail_id"=>"8", "price_id"=>"11"}], "subtotal"=>"111990", "tax"=>"0", "comission"=>"0", "total"=>"111990"}, "product_list"=>"1", "button"=>""}
我创建订单的代码可以正常工作,但我无法添加详细信息。
订单控制器
def create
# Creates the order removing the order details from the hash
@order = Order.create(order_params.except!(:order_detail))
# Set all the details into an empty array
order_details_attributes = order_params[:order_detail]
order_details_attributes.each do |order_detail_attributes|
# Fill the params with order_id and creates the detail
order_detail_attributes["order_id"] = @order.id
@order_detail = OrderDetail.create(order_detail_attributes)
end
respond_to do |format|
if @order.save
format.html { redirect_to @order, notice: 'Order was successfully created.' }
format.json { render :show, status: :created, location: @order }
else
format.html { render :new }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
def order_params
params.require(:order).permit(:customer_id, :subtotal, :tax, :comission, :total, :invoice, :shipping_id, :order_detail, order_details_attributes: [:product_id, :product_detail_id, :price_id])
end
我收到这个错误:
undefined method `delete' for nil:NilClass
order_details_attributes = order_params[:order].delete(:order_detail)
有什么不好的?我真的需要帮助:(
谢谢!!
order_params
没有键 :order
,它只有你在 permit
方法中定义的键 order_params
。实际上,您不需要手动创建 children 记录,因为 Rails 可以自动创建。看看这个:http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
你只需要在订单模型中添加accepts_nested_attributes_for :order_details
,创建订单时填写order_details_attributes
参数(目前你填写order_detail
,你需要修复你的表格才能成为order_details_attributes
,因为这是 Rails 约定之一,或者您可以为此使用 fields_for
帮助器)。然后您只需以标准方式创建订单,如 @order = Order.new(order_params)
和 @order.save
,您将获得一起创建的订单和订单详细信息。
这在Rails中真是一团糟。我只能推荐你阅读我发布的 link 并使用 Google 查找一些教程。
至于你得到的错误:
undefined method `delete' for nil:NilClass
order_params
中没有 :order
键。它在 params
中,但不在 order_params
中,因为您调用了 require(:order)
。所以 order_params
returns 只有你在 permit
方法中指定的键。但是 :order_detail
将是空的,因为您没有将它描述为具有某些键的数组(就像您对 order_details_attributes
所做的那样)。
所以,你的问题是你试图实现嵌套属性,但是你传递了 :order_detail
而不是 :order_details_attributes
(嗯,但你仍然在强参数中有它)并尝试创建 children手动关系。不要这样做,只需使用 Rails 提供给您的内容即可。
有两种方法:
您继续使用 order_detail
参数。在这种情况下,您需要将控制器中的 order_params
更改为如下所示:
params.require(:order).permit(:customer_id, :subtotal, :tax, :comission, :total, :invoice, :shipping_id, order_detail: [:product_id, :product_detail_id, :price_id])
(只需将 order_details_attributes
替换为 order_detail
)
然后代替
order_details_attributes = order_params[:order].delete(:order_detail)
你会
order_details_attributes = order_params[:order_detail]
(这里不需要 delete
,因为 order_params
是一种 returns 哈希的方法)
并保留其余的控制器代码。而且您不需要嵌套属性,因为您不使用它(糟糕的方式)。
- 您完全使用了嵌套属性。我在下面的评论中描述了如何做到这一点。您还需要调整 jquery 代码以生成
order_details_attributes
而不是 order_detail
.
我有以下表格:
当用户从下拉列表中选择产品时,将触发 ajax 以查找单个产品的库存以将详细信息附加到 table。
用户可以在订单中附加产品详细信息。
最后我得到了类似的东西:
{"utf8"=>"✓", "authenticity_token"=>"xmlzMouWp0QGUnpKeawQ8OCPJ/GlF2bp0kn97ra2Qyb7TgsCkXmJEGD1l/oZitn+VPVJRc8x79/kTUtgbbDr0A==", "order"=>{"customer_search"=>"", "customer_id"=>"2", "product_search"=>"", "order_detail"=>[{"product_id"=>"10", "product_detail_id"=>"13", "price_id"=>"12"}, {"product_id"=>"1", "product_detail_id"=>"8", "price_id"=>"11"}], "subtotal"=>"111990", "tax"=>"0", "comission"=>"0", "total"=>"111990"}, "product_list"=>"1", "button"=>""}
我创建订单的代码可以正常工作,但我无法添加详细信息。
订单控制器
def create
# Creates the order removing the order details from the hash
@order = Order.create(order_params.except!(:order_detail))
# Set all the details into an empty array
order_details_attributes = order_params[:order_detail]
order_details_attributes.each do |order_detail_attributes|
# Fill the params with order_id and creates the detail
order_detail_attributes["order_id"] = @order.id
@order_detail = OrderDetail.create(order_detail_attributes)
end
respond_to do |format|
if @order.save
format.html { redirect_to @order, notice: 'Order was successfully created.' }
format.json { render :show, status: :created, location: @order }
else
format.html { render :new }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
def order_params
params.require(:order).permit(:customer_id, :subtotal, :tax, :comission, :total, :invoice, :shipping_id, :order_detail, order_details_attributes: [:product_id, :product_detail_id, :price_id])
end
我收到这个错误:
undefined method `delete' for nil:NilClass
order_details_attributes = order_params[:order].delete(:order_detail)
有什么不好的?我真的需要帮助:(
谢谢!!
order_params
没有键 :order
,它只有你在 permit
方法中定义的键 order_params
。实际上,您不需要手动创建 children 记录,因为 Rails 可以自动创建。看看这个:http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
你只需要在订单模型中添加accepts_nested_attributes_for :order_details
,创建订单时填写order_details_attributes
参数(目前你填写order_detail
,你需要修复你的表格才能成为order_details_attributes
,因为这是 Rails 约定之一,或者您可以为此使用 fields_for
帮助器)。然后您只需以标准方式创建订单,如 @order = Order.new(order_params)
和 @order.save
,您将获得一起创建的订单和订单详细信息。
这在Rails中真是一团糟。我只能推荐你阅读我发布的 link 并使用 Google 查找一些教程。
至于你得到的错误:
undefined method `delete' for nil:NilClass
order_params
中没有 :order
键。它在 params
中,但不在 order_params
中,因为您调用了 require(:order)
。所以 order_params
returns 只有你在 permit
方法中指定的键。但是 :order_detail
将是空的,因为您没有将它描述为具有某些键的数组(就像您对 order_details_attributes
所做的那样)。
所以,你的问题是你试图实现嵌套属性,但是你传递了 :order_detail
而不是 :order_details_attributes
(嗯,但你仍然在强参数中有它)并尝试创建 children手动关系。不要这样做,只需使用 Rails 提供给您的内容即可。
有两种方法:
您继续使用
order_detail
参数。在这种情况下,您需要将控制器中的order_params
更改为如下所示:params.require(:order).permit(:customer_id, :subtotal, :tax, :comission, :total, :invoice, :shipping_id, order_detail: [:product_id, :product_detail_id, :price_id])
(只需将 order_details_attributes
替换为 order_detail
)
然后代替
order_details_attributes = order_params[:order].delete(:order_detail)
你会
order_details_attributes = order_params[:order_detail]
(这里不需要 delete
,因为 order_params
是一种 returns 哈希的方法)
并保留其余的控制器代码。而且您不需要嵌套属性,因为您不使用它(糟糕的方式)。
- 您完全使用了嵌套属性。我在下面的评论中描述了如何做到这一点。您还需要调整 jquery 代码以生成
order_details_attributes
而不是order_detail
.