1

i have an array of selected product_ids and product quantities i need to insert through active records into the rails database model in a single HTTP request. the orderitem arrays belong to an order_detail active record model. I need to be able to record this items into tghe database on clicking the "submit order" botton from the react client side.

def create
    order_detail = @user.order_details.create(order_detail_params)
    @order_item = OrderItem.create(order_item_params.merge(order_detail_id: order_detail.id))

    if @order_item.valid?
    render json: @order_item, status: :created
    else
    render json: @order_item.errors, status: :unprocessable_entity
end
 end

def order_item_params
   params.require(:order_item).permit([:quantity, :product_id])
end
def order_detail_params
   params.require(:order_detail).permit(:total )
end

1 Answers1

0

You can use accepts_nested_attributes_for in your ActiveRecord model to create associated records more easily. In this case, you'll need to make a few changes to your OrderDetail model and the OrderDetailsController:

class OrderDetail < ApplicationRecord
  belongs_to :user
  has_many :order_items, dependent: :destroy

  accepts_nested_attributes_for :order_items

  # Your other validations and methods
end
class OrderDetailsController < ApplicationController
  before_action :set_user

  def create
    order_detail = @user.order_details.new(order_detail_params)

    if order_detail.save
      render json: order_detail, status: :created, include: :order_items
    else
      render json: order_detail.errors, status: :unprocessable_entity
    end
  end

  private

  def set_user
    @user = User.find(params[:user_id]) # Or, you can use current_user if you have authentication set up
  end

  def order_detail_params
    params.require(:order_detail).permit(:total, order_items_attributes: [:product_id, :quantity])
  end
end

With this setup, Rails will automatically create associated OrderItem records for you when you create an OrderDetail record.

Here's an example of the JSON payload:

{
  "order_detail": {
    "total": 100.00,
    "order_items_attributes": [
      {
        "product_id": 1,
        "quantity": 2
      },
      {
        "product_id": 3,
        "quantity": 1
      }
    ]
  }
}
steev
  • 304
  • 1
  • 7
  • This was brilliantly answered and the code worked so well. thanks a lot – morris menanya Mar 25 '23 at 07:58
  • Love to hear it! If you haven't used `accepts_nested_attributes_for` before, check out some of the other features as well. You can use the same format to update children. If you pass the ID, it will update, without an ID it will create. If you `allow_destroy: true` you can delete children by passing `_destroy: true`. https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html – steev Mar 25 '23 at 15:46