eloquentrelationshiphas-manyhas-one

Convert Eloquent HasMany relationship to a HasOne?


Ok, i have model A that is linked to many model B, so model A have a hasMany relationship to model B and model B has a belongsTo relationship to model A.

But, amongst all those B there is a particular one, e.g. the one with the higher value, that i want model A to have a dedicated relationship with.

I know i can create a second relationship in model A that re-use the old one and add all the scopes and condition i want, but since i'm building this new relationship from a hasMany, it will return always, no matter what, a collection of results.

Is there a way to have it return a single result instead than a collection? I know i can add a first(), but this involve in using this new relationship as a function, i.e. always with parenthesis, and if possible i would like to still use it the eloquent way.

Is it possible to do that? if yes, how?


Solution

  • How about this:

    public function Bs()
    {
        return $this->hasMany(B::class);
    }
    
    public function B()
    {
        $builder = $this->Bs()->latest(); // Add your own conditions etc...
    
        $relation = new HasOne($builder->getQuery(), $this, 'a_id', 'id');
    
        return $relation; // or return $relation->withDefault();
    }
    

    Update:

    A new one-of-many relationship shipped with Laravel 8.42. You probably want to use this instead:

    public function B(): HasOne
    {
        return $this->hasOne(B::class)->latestOfMany();
    }