嵌套属性使用空值rails 5保存

时间:2017-11-13 07:38:15

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

我有两个型号。订单和订单有很多order_products。 我正在使用angularjs post request创建订单。 角度控制器:

<!DOCTYPE html>
<html>
<body>

<select>
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="opel">Opel</option>
  <option value="audi">Audi</option>
</select>
  
</body>
</html>

以下是请求。

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

它创建订单产品,但所有属性都设置为null。以下是输出。它在导轨4中工作得非常好,但不能在导轨5中工作。

@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])

2 个答案:

答案 0 :(得分:0)

默认情况下不允许

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]

因此,您最好注意从角度发送参数:

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

答案 1 :(得分:0)

它最终加入了

@order.order_products_attributes = order_products_attributes_params[:order_products_attributes]‌​

到wasif的回答。

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