简体   繁体   中英

Laravel Dynamic Polymorphic Relation

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

  • Order
  • Order Item (has orderable_type and orderable_id that refer to Product models)
  • Product (multiple 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).

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM