Lukas Derksen
Lukas Derksen

Reputation: 121

Loading two-way recursive relation in laravel

In a project I'm currently working on, I have to link two entities of the same model together, creating a recursive relation. This will create an entry in the database in which one of the entities is marked as the 'parent_entity' and the other as the 'child_entity'. Therefore, I am able to load the parents of an entity and the children of an entity separately. However, I would like to be able to load both the relations simultaneously and return them together. Would this be in any way possible?

Here is what I came up with up until now, although now I'm not yet able to call entity->load('linkedDatasets')

class Dataset extends Model implements Auditable
{
    use Encryptable;
    use \OwenIt\Auditing\Auditable;

    public function parentDatasets() {
        return $this->belongsToMany(Dataset::class, 'linked_datasets', 'dataset_id', 
            'linked_dataset_id');
    }

    public function childDatasets() {
        return $this->belongsToMany(Dataset::class, 'linked_datasets', 'linked_dataset_id', 
            'dataset_id');
    }

    public function linkedDatasets() {
        $children = $this->childDatasets;
        $parents = $this->parentDatasets;
        return $parents->merge($children);
    }
}

Upvotes: 2

Views: 144

Answers (1)

mrhn
mrhn

Reputation: 18916

You method works fine, but instead of loading the new method, which you can't due to it being a method not a relation, just include them with the with() method.

Dataset::with('parentDatasets', 'childDatasets')->get($id);

If you are using standard transformation, you can convert the method to an getter to make it act like an database column. Now you can fetch it as $dataset->linked_datasets. Bonus points, concat is more effective than merge.

public function getLinkedDatasetsAttrbiute() {
    $children = $this->childDatasets;
    $parents = $this->parentDatasets;
    return $parents->concat($children);
}

Now you just append it to the Dataset.php model., for it to be automatically serialized.

protected $appends = ['linked_datasets'];

Upvotes: 2

Related Questions