staudenmeir / belongs-to-through

Laravel Eloquent BelongsToThrough relationships
MIT License
1.15k stars 88 forks source link

BelongsToThrough when the model to recover is polymorphic (morphTo) #77

Closed joslingax closed 1 year ago

joslingax commented 1 year ago

Hi,

How can i recover C or D with belongsToThrough when i have to deal with a polymorphic relation A → belongs to → B→ belongs to → C or D

 in A
public function declarant()
{
    return $this->belongsTo('\Modules\Declarants\Models\Declarant', 'declarant_id', 'id');
}

in B
public function declarantable()
{
    return $this->morphTo('declarantable', 'declarantable_type', 'declarantable_id');
}

declarantable_id can belong to C or D

joslingax commented 1 year ago

Example

joslingax commented 1 year ago

i d like to retrieve C or D from A with belongsToThrough knowing B has a polymorphic relation like this public function declarantable() { return $this->morphTo('declarantable', 'declarantable_type', 'declarantable_id'); }

staudenmeir commented 1 year ago

Hi @joslingax, This is a bit more complicated, but you can achieve it with one of my other packages: https://github.com/staudenmeir/laravel-merged-relations

  1. Define the relationships:
class A extends Model
{
    use \Staudenmeir\LaravelMergedRelations\Eloquent\HasMergedRelationships;

    public function declarantables()
    {
        return $this->mergedRelation('declarantables', 'b_id');
    }

    public function cs()
    {
        return $this->morphedByMany(C::class, 'declarantable', 'b_s', 'id', null, 'b_id');
    }

    public function ds()
    {
        return $this->morphedByMany(D::class, 'declarantable', 'b_s', 'id', null, 'b_id');
    }
}
  1. Create the merge view in a migration:
use Staudenmeir\LaravelMergedRelations\Facades\Schema;

Schema::createOrReplaceMergeView(
    'declarantables',
    [(new A())->cs(), (new A())->ds()]
);

declarantables() always returns a collection, so you need to take the first item:

$declarantable = $a->declarantables()->first();