staudenmeir / eloquent-has-many-deep

Laravel Eloquent HasManyThrough relationships with unlimited levels

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

hasManyDeepFromRelations ignores limit

n1xn opened this issue · comments

commented

Hi, thanks for this lib it works really great!
I may have one issue with it - you can see the tinker commands for reference.

Doctor::find(3009)->patients()->pluck('id')
//    all: [
//      3273,
//    ],

Patient::find(3273)->patientProtocols()->count()
// 3

Patient::find(3273)->latestPatientProtocol()->count()
// 1

Doctor::find(3009)->latestPatientProtocols()->count()
// 3     <- this should be 1
class Doctor extends BaseModel
{
    use HasRelationships, HasEagerLimit;

    public function latestPatientProtocols(): HasManyDeep
    {
        return $this->hasManyDeepFromRelations($this->patients(), (new Patient())->latestPatientProtocol());
    }

    public function patients(): HasMany
    {
        return $this->hasMany(Patient::class);
    }
}

class Patient extends BaseModel
{
    use HasEagerLimit;

    public function latestPatientProtocol(): HasOne
    {
        return $this->hasOne(PatientProtocol::class)->latestOfMany('created_at')->limit(1);
    }

    public function patientProtocols(): HasMany
    {
        return $this->hasMany(PatientProtocol::class);
    }
}


class PatientProtocol extends Model
{
     public function patient(): BelongsTo
    {
        return $this->belongsTo(Patient::class);
    }
}

Hi @n1xn,
Use hasOneDeepFromRelations() when you only want to get a single result:

class Doctor extends BaseModel
{
    use HasRelationships, HasEagerLimit;
 
    public function latestPatientProtocols(): HasOneDeep
    {
         return $this->hasOneDeepFromRelations($this->patients(), (new Patient())->latestPatientProtocol());
    }
}
commented

Hi @staudenmeir and thank you for your quick answer.
You know I want to retrieve the latestPatientProtocol for each patient from a doctor, not every.

Maybe if I update the console values it gets more clear.

Doctor::find(3007)->patients()->count()
// 22

Doctor::find(3009)->latestPatientProtocols()->count()
// 36     <- this should be 22

It is returning 36 because it loads all patientProtocols and a Patient usually have more than one PatientProtocol. But I am only interested into the latest for each patient. Kind of a 'nested hasOne'.

It's not possible to achieve this with a deep relationship.

You need to run separate queries and then collect all the protocols:

$patients = Doctor::find($id)->patients()->with('latestPatientProtocol')->get();

$latestPatientProtocols = $patients->pluck('latestPatientProtocol');
commented

Thats unfortunate, thank you for your help!