【问题标题】:Nested attributes saving with empty values rails 5使用空值保存的嵌套属性 rails 5
【发布时间】:2017-11-13 07:38:15
【问题描述】:

我有两个模型。 order 和 order 有很多 order_products。 我正在使用 angularjs 发布请求来创建订单。 角度控制器:

return $scope.submitForm = function() {
    var order_products_attributes;
    if ($scope.buyer.selected_item) {
        $scope.order.company_id = $scope.buyer.selected_item.id;
    }
    order_products_attributes = [];
    var qtt = 0
    $scope.op.forEach(function(obj) {
        var newObj;
        var total = parseInt(obj.quantity) * parseInt(obj.batch.selected_item[0].pack_size);
        qtt= qtt+total;
        newObj = {
            product_id: parseInt(obj.product.selected_item[0].id),
            product_batch_id: parseInt(obj.batch.selected_item[0].id),
            price: parseInt(obj.price),
            quantity: parseInt(obj.quantity),
            free_quantity: parseInt(obj.free_quantity),
            total_quantity:total ,
            total_amount: parseInt(obj.total_amount)
        };
        return order_products_attributes.push(newObj);
    });
    $scope.order.order_products_attributes = order_products_attributes;
    $scope.order.price = $scope.amount;
    $scope.order.discount = $scope.discount;
    $scope.order.quantity = qtt;
    $scope.order.status = 'Booked'
    // $scope.order.dc_date = $("#orderDate").find("input").val()
    $scope.order.order_date = $("#orderDate").find("input").val()
    // $scope.order.delivery_date = $("#orderDate").find("input").val()
    $scope.order.delivery_date = $("#deliveryDate").find("input").val()

    var st = $("#orderDate").find("input").val().split("/");
    var dd = new Date(st[2],st[1]-1,st[0]);
    dd.setDate(dd.getDate()+30);
    $scope.order.due_date = dd;

    $scope.order.authenticity_token = $scope.authenticity_token;
    $scope.order.type = type;
    // if($scope.p_type.selected_item)
    //     $scope.order.payment_type = $scope.p_type.selected_item.value;
    console.log($scope.order)


    return $http.post('/orders', $scope.order).then(function(response) {
        response.data;

        $window.location.href = '/orders/invoice_print/'+response.data.id;
    });
};

以下是请求。

Parameters: {"company_id"=>13, "order_products_attributes"=>[{"product_id"=>6, "product_batch_id"=>26, "price"=>1100, "quantity"=>1, "free_quantity"=>nil, "total_quantity"=>10, "total_amount"=>11000}], "price"=>11000, "discount"=>0, "quantity"=>10, "status"=>"Booked", "order_date"=>"13/11/2017", "delivery_date"=>"13/11/2017", "due_date"=>"2017-12-12T19:00:00.000Z", "authenticity_token"=>"OJx5FtSx6+e0FEhlRdUIqzfW7OhA18/Y3B3ETAqye8en3WC49QhR0smmz3MGoqRfsqmckMFLhVsz2ldRnmDXXA==", "type"=>"RegisteredOrder", "order"=>{"company_id"=>13, "price"=>11000, "quantity"=>10, "order_date"=>"13/11/2017", "delivery_date"=>"13/11/2017", "discount"=>0, "type"=>"RegisteredOrder", "due_date"=>"2017-12-12T19:00:00.000Z"}}

我的模型是

class Order < ApplicationRecord
    has_many :order_products, inverse_of: :order, :dependent => :destroy
    accepts_nested_attributes_for :order_products
end
class OrderProduct < ApplicationRecord
    belongs_to :product
    belongs_to :order
end

控制器:

@order = Order.new(order_params)
status_value_id = StatusValue.where(:status_val=> 'Booked').where(:status_type => 'sale-order').first.id
@order.order_products_attributes = params["order_products_attributes"]
@order.save


params.require(:order).permit(:status,:company_id, :type, :price,:quantity,:discount, :order_date, :delivery_date ,:due_date, :dc_date, :dc_number, :order_number, :invoice_number,  :special_instruction,order_products_attributes: [:id,:product_id, :description, :product_batch_id, :quantity,:pack_size,:total_quantity, :price, :discount, :discount_percentage, :total_amount])

它创建订单产品,但所有属性都设置为空。以下是输出。它在 rails 4 中运行良好,但在 rails 5 中无法正常工作。

INSERT INTO "orders" ("company_id", "price", "quantity", "order_date", "delivery_date", "created_at", "updated_at", "discount", "order_number", "invoice_number", "type", "dc_number", "user_id", "due_date", "status_value_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) RETURNING "id"  [["company_id", 13], ["price", 11000.0], ["quantity", 10], ["order_date", 2017-11-12 19:00:00 UTC], ["delivery_date", 2017-11-12 19:00:00 UTC], ["created_at", 2017-11-13 06:06:52 UTC], ["updated_at", 2017-11-13 06:06:52 UTC], ["discount", 0.0], ["order_number", 26], ["invoice_number", 26], ["type", "RegisteredOrder"], ["dc_number", "10"], ["user_id", 1], ["due_date", 2017-12-12 19:00:00 UTC], ["status_value_id", 9]]
SQL (16.0ms)  INSERT INTO "order_products" ("order_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["order_id", 90], ["created_at", 2017-11-13 06:06:52 UTC], ["updated_at", 2017-11-13 06:06:52 UTC]]

【问题讨论】:

  • 您从角度发布请求中获得的参数不包含任何:order 属性,因此像params.require(:order).permit(...) 这样要求它会导致ActionController::ParameterMissing: param is missing or the value is empty: order
  • 还要确保从 angular 设置 Content-Type: application/json 标头,以便将 json 解析为 paramsOrdersController
  • 该错误没有显示,而是订单正在保存。
  • http.post('/orders', $scope.order).then(function(response) {}) 这是我的请求。
  • 你能分享你原来的orders#create行动吗?这样我们就可以了解如何以正确处理强参数的方式重写它

标签: ruby-on-rails nested-forms nested-attributes strong-parameters


【解决方案1】:

它终于在添加

的情况下工作了
@order.order_products_attributes = order_products_attributes_params[:order_products_attributes]‌​

wasif 的回答。

order_products_attributes_params 返回一个哈希 { [ {} , {} ] },所以我从中提取了 order_products_attributes 数组

【讨论】:

    【解决方案2】:

    params["order_products_attributes"] 默认是不允许的。所以你必须像这样允许它:

    private
    
    def order_products_attributes_params
      params.permit(order_products_attributes: [:product_id, :product_batch_id, :price, :quantity, :free_quantity, :total_quantity, :total_amount])
    end
    

    并在分配给@order 时使用它并保存如下:

    @order.order_products_attributes = order_products_attributes_params[:order_products_attributes]
    @order.save
    

    顺便说一句,上述解决方案并不以 Rails 方式起作用。无论如何它可能会起作用。为了使其成为标准,它应该如下所示:

    @order = Order.new(order_params)
    @order.save # this should create the new :order along with a nested :order_product
    
    # the following should not be needed if you pass the parameters from angular in correct way
    # @order.order_products_attributes = order_products_attributes_params[:order_products_attributes]
    

    因此,您最好注意从 angular 发送参数,如下所示:

    Parameters:
    {  
      "authenticity_token": "OJx5FtSx6+e0FEhlRdUIqzfW7OhA18/Y3B3ETAqye8en3WC49QhR0smmz3MGoqRfsqmckMFLhVsz2ldRnmDXXA==",
      "order": {
        "company_id": 13,
        "price": 11000,
        "discount": 0,
        "quantity": 10,
        "status": "Booked",
        "order_date": "13/11/2017",
        "delivery_date": "13/11/2017",
        "due_date": "2017-12-12T19:00:00.000Z",
        "type": "RegisteredOrder",
        "order_products_attributes": [  
          {  
            "product_id": 6,
            "product_batch_id": 26,
            "price": 1100,
            "quantity": 1,
            "free_quantity": nil,
            "total_quantity": 10,
            "total_amount": 11000
          }
        ]
      }
    }
    

    order_params 看起来像:

    private
    
    def order_params
      params.require(:order).permit(:company_id, :price, :discount, :quantity,
         :status, :order_date, :delivery_date, :due_date, :type,
         :order_products_attributes: [
           :product_id, :product_batch_id, :price, :quantity, :free_quantity,
           :total_quantity, :total_amount
         ]
      )
    end
    

    【讨论】:

    • 不允许的参数:company_id、order_products_attributes、price、discount、quantity、status、order_date、delivery_date、due_date、authentity_token、type、order
    • 我的错。编辑。请再次关注并更新您的报告
    • 已经在尝试了。这次给出了一些类型错误。让我检查一下。
    • 使用所有嵌套属性进行编辑。现在它应该可以工作了。
    • 它最终使用了这个'@order.order_products_attributes = order_products_attributes_params[:order_products_attributes]' order_products_attributes_params 返回了一个哈希 { [ {} , {} ] } 所以我从中提取了 order_products_attributes 数组。顺便说一句,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多