javediq_143's avatar

Multiple Polymorphic Relations in same Model

Hello All,

Continuing with my Ecommerce site where users can order food online, I'm stuck at another stage. Below are the tables in my app:

// users TABLE [Registered user of my site]
id, name and other fields
// guests TABLE [Guest user of my site]
id, name and other fields

Here, I have a Polymorphic Many to Many Relation between User <=> Order <=> Guest set in order table as:

// orders TABLE
id
orderable_id  // Id of user who has placed the order
orderable_type // Type of a user - Guest or Registered
cart_amount
payment_mode // Currently it is set as enum('cash', 'cashless')
payment_status // Set as enum('pending', 'received', 'refund', 'refunded')
and other fields

Now going further in my development, I need to create 2 more tables to store payment details as:

  1. cash Table [Storing details of payment made in CASH]
  2. cashless Table [Storing details of payment made via CASHLESS methods]

I dont know whether i should create a relation between these 2 tables and the orders table? I believe i had to and that should be a POLYMORPHIC MANY TO MANY relation; but I dont know how to achieve that 'coz i'm already having a polymorphic relation in orders table [between users and guests].

Can anyone guide me in this?

Thanks in advance.

Much Regards Javed

0 likes
4 replies
morcen's avatar
morcen
Best Answer
Level 2

My suggestion would be just to create a table payment, with a boolean column is_cash. It will have a field order_id, so it's a many-to-one relationship with the orders table. With this approach, you can also accommodate partial cash-partial card payment, by inserting 2 payment records but with different values for is_cash column. If payment details of cash and cashless are different, you can either have a separate table payment_details or just have a json column to store the details there.

javediq_143's avatar

Hello Morcen,

Thanks a lot for your solution. From your view point, this is what i think needs to be done:

Create a table PAYMENTS with below fields

id
order_id
amount_received
is_cash
created_at

Since there would be no partial cash-partial card payment type, this table will have ONE-TO-ONE relation with ORDERS table?

Further to store payment details [only card payment], i would need to create a table PAYMENT_DETAILS with below fields:

id
payment_id
fields for storing card type and bank details and so on

PAYMENT_DETAILS details will also have ONE-TO-ONE relation with PAYMENTS tables.

Am I correct ?

morcen's avatar

Yes, best of luck to your project!

javediq_143's avatar

Hello morcen,

As per your suggestion, I have implemented the above solution and it works absolutely fine. Thanks a lot for your timely support and guidance.

For any one facing the same issue, can create tables as per the structure given by me and define relationships as below:

// Order model
class Order extends Model
{
    // your other relations or methods

    public function payment()
    {
        return $this->hasOne('App\Payment');
    }
}

// Payment model
class Payment extends Model
{
    // your other relations or methods

    public function order()
    {
        return $this->belongsTo('App\Order');
    }
    
    public function payment_detail()
    {
        return $this->hasOne('App\Payment_detail');
    }
}

// Payment model
class Payment_detail extends Model
{
    // your other relations or methods

    public function payment()
    {
        return $this->belongsTo('App\Payment');
    }
}

// IN YOUR CONTROLLER CLASS ADD BELOW CODE TO SAVE THE PAYMENT AND ITS DETAILS
// GET THE ORDER OBJECT
$orderTrackId = \Session::get('track_id');
$objOrder = Order::getOrderByTrackId($orderTrackId);

// INSERT PAYMENT RECORD
$objPayment = new Payment(['amount_received'=>$objOrder->payable_amount, 'is_cash'=>'no']);
$objOrder->payment()->save($objPayment);

// INSERT PAYMENT DETAIL RECORD
$objPaymentDetail = new Payment_detail(['card_number'=>$request->txtCardNum, 'card_type'=>$request->slctCardType]);
$objPayment->payment_detail()->save($objPaymentDetail);
1 like

Please or to participate in this conversation.