Need help with self-references in manytomany -> manytomany
vaniok010 opened this issue · comments
I have 2 models/tables:
products
oems
and I have pivot table "oem_product" with "own" pivot field. Each product has multiple oems, own oem (where own = 1) and analog oems (where own = 0)
oem_id | product_id | own |
---|---|---|
1 | 1 | 1 |
2 | 1 | 0 |
3 | 1 | 0 |
1 | 2 | 0 |
2 | 2 | 0 |
3 | 2 | 1 |
in my Product model, here is my belongstomany for analogOems:
public function oems(): BelongsToMany
{
return $this->belongsToMany(Oem::class)
->withPivot(['own'])
->using(OemProduct::class);
}
public function analogOems(): BelongsToMany
{
return $this->oems()->wherePivot('own', false);
}
in my Oem model, here is my belongstomany for ownProducts:
public function products(): BelongsToMany
{
return $this->belongsToMany(Product::class)
->withPivot(['own'])
->using(OemProduct::class);
}
public function ownProducts(): BelongsToMany
{
return $this->products()->wherePivot('own', true);
}
i am trying to create a analogsThroughOems relationship in the product model:
public function analogsThroughOems()
{
return $this->hasManyDeepFromRelations((new Oem())->setAlias('analogs')->ownProducts(), (new Product())->analogOems());
}
this gives me the following error:
Call to undefined relationship [analogsThroughOems] on model [App\Models\Product].
i would like to get all the analogs products for a products through the pivot table
Product::query()->with('analogsThroughOems')->whereIn('id', [1])->get();
in analogsThroughOems I want to receive products with ids [2] for examle oem_product table
Hi @vaniok010,
this gives me the following error:
Call to undefined relationship [analogsThroughOems] on model [App\Models\Product].
How are you trying to use the analogsThroughOems
relationship in this case?
like this
Product::query()->with('analogsThroughOems')->whereIn('id', [1])->get();
My custom relation looks like this
public function analogsThroughOems(): BelongsToMany
{
$instance = $this->newRelatedInstance(Product::class);
/** @var Builder $relationQuery */
$relationQuery = $instance->newQuery();
$relationQuery->join('oem_product as op1', 'op1.product_id', '=', 'products.id');
$relationQuery->join('oem_product as op2', 'op2.oem_id', '=', 'op1.oem_id');
$relationQuery->where('op1.own', '=', 0);
$relationQuery->where('op2.own', '=', 1);
return $this
->newBelongsToMany(
$relationQuery,
$this,
'products as analogs',
'products.id',
'analogs.id',
$this->getKeyName(),
'op2.product_id'
)
->select('analogs.*');
}
@staudenmeir I think I did it, thank you
public function analogsThroughOems(): HasManyDeep
{
return $this->hasManyDeep(
Product::class,
['oem_product as analog_oems', Oem::class, 'oem_product as own_oems'],
['analog_oems.product_id', 'id', 'own_oems.oem_id', 'id'],
['id', 'analog_oems.oem_id', 'id', 'own_oems.product_id']
)->where('analog_oems.own', false)->where('own_oems.own', true);
}