Home > Net >  Polymorphic relationship with other polymorphic realtion?
Polymorphic relationship with other polymorphic realtion?

Time:02-23

I have order and return tables which have a created_by and accepted_by field where the corresponding user id is stored. But now I would like to have multiple types for created_by and accepted_by instead of only user type. Assume a company could also create or accept the order/return.

I was thinking of a polymorphic one to many relationship. Let’s name this table participants. Something like:

ID created participantable_id participantable_type
1 1 1 user
2 0 11 company

This works either for order or return but not both. Is it practically to add extra colums to participants like trx_id and trx_type (order/return)?

How would the realtionships looks like to perform queries like:

$order->createdBy // should give me either user or company model
$order->acceptedBy
$return->createdBy
$return->acceptedBy

Or is there even a cleaner solution I am overlooking? Thanks!

CodePudding user response:

It would be 1:N polymorphic relationships so no need for an extra table. The structure can be found in the documentation

Your Order and Return model need to have the columns created_by_id, created_by_type, accepted_by_id, accepted_by_type.

                ______ (1) Company
               /
Order (N) ----<
               \______ (1) User

                 _____ (1) Company
                /
Return (N) ----<
                \_____ (1) User

class Order extends Model
{
    public function created_by()
    {
        return $this->morphTo(__FUNCTION__, 'created_by_type', 'created_by_id');
    }

    public function accepted_by()
    {
        return $this->morphTo(__FUNCTION__, 'accepted_by_type', 'accepted_by_id');
    }
}
class Return extends Model
{
    public function created_by()
    {
        return $this->morphTo(__FUNCTION__, 'created_by_type', 'created_by_id');
    }

    public function accepted_by()
    {
        return $this->morphTo(__FUNCTION__, 'accepted_by_type', 'accepted_by_id');
    }
}
class User extends Authenticatable
{
    public function created_orders()
    {
        return $this->morphMany(Order::class, 'created_by');
    }

    public function accepted_orders()
    {
        return $this->morphMany(Order::class, 'accepted_by');
    }

    public function created_returns()
    {
        return $this->morphMany(Return::class, 'created_by');
    }

    public function accepted_returns()
    {
        return $this->morphMany(Return::class, 'accepted_by');
    }
}
class Company extends Model
{
    public function created_orders()
    {
        return $this->morphMany(Order::class, 'created_by');
    }

    public function accepted_orders()
    {
        return $this->morphMany(Order::class, 'accepted_by');
    }

    public function created_returns()
    {
        return $this->morphMany(Return::class, 'created_by');
    }

    public function accepted_returns()
    {
        return $this->morphMany(Return::class, 'accepted_by');
    }
}
  • Related