Mithc
Mithc

Reputation: 891

Laravel Dynamic Polymorphic Relation

So I'm trying to make dynamic relationships for order items in Laravel. I have 3 main types of models:

And my goal is to have the Order model to be able to have order items but also include their respective product models (orderable).

These are my models:

class Order extends Model
{
    public function items()
    {
        return $this->hasMany(OrderItem::class);
    }
}

class OrderItem extends Model
{
    public function order()
    {
        return $this->belongsTo(Order::class);
    }

    public function orderable()
    {
        return $this->morphTo();
    }
}

class ProductType extends Model
{
    public function orderItem()
    {
        return $this->morphOne(OrderItem::class, 'orderable');
    }
}

So, when I call Order::with('items')->get() I get the collection of \App\Models\OrderItem included:

Illuminate\Database\Eloquent\Collection {#4059
  all: [
    App\Models\Order {#4016
      id: 1,
      ...
      items: Illuminate\Database\Eloquent\Collection {#4026
        all: [
          App\Models\OrderItem {#4063
            id: 1,
            orderable_type: "ProductType",
            orderable_id: 1,
            ...
          },
        ],
      },
    },
  ],
}

And what I expect to have is:

Illuminate\Database\Eloquent\Collection {#4059
  all: [
    App\Models\Order {#4016
      id: 1,
      ...
      items: Illuminate\Database\Eloquent\Collection {#4026
        all: [
          App\Models\OrderItem {#4063
            id: 1,
            orderable_type: "ProductType",
            orderable_id: 1,
            orderable: App\Models\Products\ProductType {
              ...
            }
            ...
          },
        ],
      },
    },
  ],
}

So it's kind of a nested with(), but not sure how to make it happen. The purpose is to have everything in a single Eloquent call instead of calling the relationship afterward (meant to be on an API Resource as well).

Upvotes: 2

Views: 914

Answers (1)

Kurt Friars
Kurt Friars

Reputation: 3764

You are looking for nested eager loading. You can use them in your case like:

Order::with('items.orderable')->get();

Upvotes: 1

Related Questions