ruby-on-railsstrong-parameters

Rails permit nested attribute


I am working on rails 6 with ruby-2.6.5 and i am working on the API. I am using nested attributes for my order as follows:-

orders_controller.rb
# frozen_string_literal: true

module Api
  module V1
    class OrdersController < Api::V1::ApiApplicationController
      before_action :validate_token

      def create
        debugger
        order = OrderInteractor.create(order_params, @user_id)
        if order.save
          render json: { 'message' => 'Order Placed' }, status: :ok
        else
          render_errors(order)
        end
      end

      private

      def order_params
        params.require(:data)
              .require(:attributes)
              .require(:order)
              .permit(:user_id, :address_id, :total_price, :payment_status,
                      :order_number, :delivery_time_slot,
                      order_details_attributes:
                      %i[price quantity order_detail_status product_id
                         order_number variant_id],
                      payment_details_attributes:
                      %i[payment_data payment_id])
      end
    end
  end
end

Api Request:-

{
    "data": {
        "attributes": {
            "order": {
                "address_id": "82",
                "delivery_time_slot": "5:00 PM - 8:00 PM(Today)",
                "order_details_attributes": [{
                    "price": "76.0",
                    "product_id": "46",
                    "quantity": "4",
                    "variant_id": "47"
                }, {
                    "price": "9.9",
                    "product_id": "30",
                    "quantity": "1",
                    "variant_id": "29"
                }],
                "payment_details_attributes": [{
                    "payment_data": {
                        "data": {
                            "nameValuePairs": {
                                "razorpay_payment_id": "pay_HiHceX2p6450Wa",
                                "org_logo": "",
                                "org_name": "Razorpay Software Private Ltd",
                                "checkout_logo": "https://cdn.razorpay.com/logo.png",
                                "custom_branding": false
                            }
                        },
                        "paymentId": "pay_HiHceX2p6450Wa",
                        "userContact": "+916494949494",
                        "userEmail": "dailyferia@gmail.com"
                    }
                }],
                "total_price": "354"
            }
        },
        "type": "orders"
    }
}

While placing order i am getting the error Unpermitted parameter: :payment_data but it's working fine for the order_details. Please help me to fix it? I also tried the below ways to fix it but nothing worked:-

payment_details_attributes: %i[:payment_data payment_id]) and `payment_details_attributes: ['payment_data', 'payment_id'])`

Solution

  • Your payment_data is a complex object, rather than the scalars that are found in your order_details_attributes

    You will need to add more to the permitted parameters, I believe the simplest solution would be:

    payment_details_attributes: [payment_data: {}]
    

    This should accept all parameters under payment_details_attributes, but it would also permit any other keys as well. You may want to be more strict and only allow the parameters specified above, in which case you could do:

    payment_details_attributes: [
      payment_data: {
        data: {
          nameValuePairs:
          %i[razorpay_payment_id org_logo org_name checkout_logo custom_branding]
        },
        :paymentId, :userContact, :userEmail
      }
    ]
    

    which should restrict the parameters to just the format used in your example.

    A few other notes:

    Lastly, I haven't tested my code above, so there could be a syntax or other error, but hopefully this points you in the right direction.