0

I have a requirement in rails api application. client can have many orders and each order belongs to a client.

class Client < ApplicationRecord
    has_many :orders
end

my order.rb is

class Order < ApplicationRecord
  belongs_to :client, dependent: :destroy
  accepts_nested_attributes_for :client
  validates_presence_of :order_amount, :service_amount, :miners_amount
end

I have a route exposed /place_order and which creates client and orders.

class OrderProcessingController < ApplicationController
    def place_order
        @order = Order.new(order_processing_params)
        if @order.save
            render json: @order
        else
            render json: @order.errors.full_messages
        end
    end

    private
    def order_processing_params
        params.require(:order).permit(:order_amount, :service_amount, :miners_amount, client_attributes: [:name, :email, :phone_number, :date])
    end
end

Everything works fine so far. Now my requirement is, i have to check the client is already present in client table. if yes add the client_id for the orders and create new order. I don't want to create new client and order every time.

how can i achieve the same in before_filter or something like that. get the client from client params and if the client present delete the params key from incoming params ???

the post data for place_order is as follows

{
     "order" : {
       "order_amount" : "10000",
        "service_amount" : "1000",
        "miners_amount" : "10000",
         "client_attributes": {
                "name": "Ajith",
                "email": "ajith@gmail.com",
                "phone_number": "12231321312",
                "date": "12/12/12"
            }
         }
  }

Thanks in advance, Ajith

Ajith
  • 325
  • 4
  • 17
  • is it mandatory to pass client attributes everytime instead of client_id?, what is the primary key for client. email? – Bijendra Jun 01 '18 at 04:49
  • params will always have the same structure. every time i place order client record must be checked. if no client found add entries to client table and order table. suppose client is already present place order. set client_id for the order. no need to create new entries each time. relationship: client has many orders. client table primary key is email. – Ajith Jun 01 '18 at 05:33

2 Answers2

1

The below code is not tested, mostly your approach should be around this

class OrderProcessingController < ApplicationController
  before_action :find_client, only: [:place_order]

  def place_order
    @order = @client.orders.new(order_processing_params)

    if @order.save
        render json: @order
    else
        render json: @order.errors.full_messages
    end
  end

private
  def order_processing_params
    params.require(:order).permit(:order_amount, :service_amount, :miners_amount, client_attributes: [:name, :email, :phone_number, :date])
  end

  def find_client
    @client = Client.find_or_create_by(email: params[:order][:client_attributes][:email])
    #below line can be improved using a method, see the last line if later you want, never update a primary key which is email in bulk params
    @client.update_attributes(name: params[:order][:client_attributes][:name], phone_number: params[:order][:client_attributes][:phone_number], date: params[:order][:client_attributes][:date])
  end

  #def get_client_params
   # params.require(:order)
  #end
end
Bijendra
  • 9,467
  • 8
  • 39
  • 66
0

I tried below approach to get a solution. not very sure that this is the right way to approach the problem

class OrderProcessingController < ApplicationController
    before_action :find_client, only: :place_order
    def place_order
        if @client.present?
            @order = @client.orders.build(order_processing_params) 
        else
            @order = Order.new(order_processing_params)

        end
        if @order.save
            render json: @order
        else
            render json: @order.errors.full_messages
        end
    end

    private
    def order_processing_params
        params.require(:order).permit(:order_amount, :service_amount, :miners_amount, client_attributes: [:name, :email, :phone_number, :date])
    end

    def find_client
        begin
            @client =  Client.find_by_email(params[:order][:client_attributes][:email])
        rescue
            nil
        end
    end
end

Thanks, Ajith

Ajith
  • 325
  • 4
  • 17