Search code examples
phpmysqllaravellaravel-6eager-loading

Laravel 6 eager loading using with() on a belongsTo relationship is only *sometimes* returning null


I am working on a project where we have a model for a service provider, the type of care provided, and the status:

Provider:

class Provider extends Model
{
    protected $table = 'providers';

    public function status() {
        return $this->belongsTo('App\Status');
    }

    public function caretype() {
        return $this->belongsTo('App\CareType', 'id');
    }
}

CareType:

class CareType extends Model
{
    protected $table = 'type_of_care';

    public function providers() {
        return $this->hasMany('App\Providers', 'type_of_care_id');
    }

    public function category() {
        return $this->belongsTo('App\CareCategory');
    }
}

Status:

class Status extends Model
{
    protected $table = 'status';

    public function providers() {
        return $this->hasMany('App\Providers');
    }
}

On the my SearchController (the controller that processes search requests for providers), the show() function using eager loading retrieves the caretype perfectly. But on the search() function that lists the collection of search results, the caretype is always listed as null.

I don't understand why it would be working in one function but not the other, especially when the code to eager load is exactly the same in both functions:

public function search(Request $request)
    {

        $validated = $request->validate([
            //I removed the validation code for this post
        ]);

        $providers = Provider::with(['status', 'caretype'])->get();

        return view('search.results', ['providers' => $providers]);

    }

    public function show($id)
    {

        $single_provider = Provider::with(['status', 'caretype'])->where('id', $id)->first();
        return view('search.details', ['provider' => $single_provider]);

    }

Any help in this would be appreciated. I know that the model and relationship foreign keys are properly defined because the show() function is able to get the caretype just fine.


Solution

  • nope. your relationship and foreign keys are not correct. as from the doc

    Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with a _ followed by the name of the primary key column. However, if the foreign key on the Child model is not like that, you may pass a custom key name as the second argument to the belongsTo method.

    you are passing the id column as the foreign key in Provider model's caretype ralation but your foreign key is type_of_care_id. so you are getting some results when the id matches but if not, you are getting null. change your relationship code to

    public function caretype()
    {
        return $this->belongsTo('App\CareType', 'type_of_care_id');
    }
    

    now again from the doc

    If your parent model does not use id as its primary key, or you wish to join the child model to a different column, you may pass a third argument to the belongsTo method specifying your parent table's custom key.

    in your case id is the primary key. so you don't have to pass the third parameter. just update the primary key reference and everything will work perfectly.