Search code examples
laravellaravel-5polymorphic-associationseloquent

Laravel 5.0 Selective Append or MorphThrough Relation


I know the subject is a little bit confusing. Let me explain.

For a medical software that I am currently developing, I have a data structure as below:

Patients has Protocols. Protocols has Examinations, Prescriptions or Reports, all polymorphic.

In some cases, I have to directly access to the Examinations of Patients. However, since this includes a polymorphic relation between Examination and Protocol, I cannot directly setup a relation method in my Patient model.

As a work around, I can set a custom getExaminationsAttribute and append this with $appends in Patient model. But this causes a whole load of data fetching when I try to get ,for example, only the name of a Patient.

Any help is appreciated.

Patient model:

class Patient extends Model{
    protected $table = 'patients';

    public function protocols(){
        return $this->hasMany('App\Protocol', 'patients_id', 'id');
    }

    protected $appends = ['examinations'];

    public function getExaminationsAttribute()
    {
        $examinations = array();

        $this->protocols->each(function($protocol) use (&$examinations){
            $protocol->examinations->each(function($examination) use (&$examinations){
                $examinations[] = $examination->toArray();
            });
        });

        return $examinations;
    }

Protocol model:

class Protocol extends Model{
    protected $table = 'protocols';

    public function patient(){
        return $this->belongsTo('App\Patient', 'patients_id', 'id');
    }

    public function examinations()
    {
        return $this->morphedByMany('App\Examination', 'protocolable');
    }

Examination model:

class Examination extends Model{

    protected $table = 'examinations';

    public function protocols()
    {
        return $this->morphToMany('App\Protocol', 'protocolable');
    }

Solution

  • As a workaround, patients_id column added to submodels of Protocol table (Examinations, Prescriptions etc.) and will be fetched via hasMany relationship.