Пожалуйста, называйте связи так, как называется модель, которую вы хотите получить.
items() ? чего? вы хотите получить CartProduct. назовите cartProducts()
очень редко, но бывает, когда CartProduct можно получить двумя способами. Тогда cartProductsByModel1(), cartProductsByModel2()
исключение - абстрактные паттерны, деревья. там можно назвать parent/children/treeParent/treeChild
<?php
Class Cart {
// ...
// вот здесь написано, что CartProduct может быть одновременно в двух и более корзинах. не могу представить себе логику, где участник заказывает на сайте товар, а потом этот же товар (который ты заморозил только что) кто-то еще заказывает
public function items(): BelongsToMany
{
return $this->belongsToMany(CartProduct::class, 'cart_products');
// Cart.hasMany(CartProduct) + CartProduct.belongsTo(Cart) + CartProduct.belongsTo(Product)
// и второе
// https://github.com/illuminate/database/blob/master/Eloquent/Concerns/HasRelationships.php#L477
// первым параметром "тип", вторым - "через что". Вы указываете, что "связь много ко многим" должна вернуть "связь много ко многим"
// при связи Много-Ко-Многим надо Cart.belongsToMany(Product::class, 'cart_products')
}
}
<?php
class CartProduct {
// ...
// здесь написано, что CartProduct старше чем Product. Это выразится в том, что вы сможете "привязать" CartProduct только из самого Product, причем один раз. Это дважды неверно.
public function product(): HasOne
{
return $this->hasOne(ProductVariant::class, 'id');
// Во первых каждый продукт с его количеством может быть куплен много раз, а вариант всего лишь показывает на его подвид
// Во вторых модель CartProduct создается позже чем Product, а значит писать $product.addChild($cartProduct) это снова дичь
// Product.hasMany(ProductVariant::class) + CartProduct.belongsTo(ProductVariant::class) + $cartProduct.associate($productVariant);
}
// то же самое. CartProduct старше чем Cart, хотя он в ней лежит. BelongsTo задает старшинство и позволяет добавлять родителя в потомок, а hasOne указывает связь, которая нужна только для select, но не годится для insert
// Потому что hasOne() - это возможность добавить потомка, причем в Eloquent нету метода addChild() его ещё и самому писать надо типа CartProduct.cart().insert($array) и это тут же нарушает идею отложенной записи, т.к. выполняет запрос немедленно и требует транзакции прямо в модели, тогда как транзакция относится к задаче, а не к модели
public function cart(): HasOne
{
return $this->hasOne(Cart::class);
}
}