Laravel Eloquent one-to-one relationship returning empty collection

I am on a project where I am using custom PKs and FKs, and I'm trying to set up a one to one relationship.

For example, in Employee.php:

public function title()
{
    return $this->hasOne('App\Title', 'TitleID');
}

On Tinker, I can retrieve an employee TitleID like so:

$employee = Employee::first();
$employee->TitleID;

Which returns:

"6"

I have now made a model: Title.php:

class Title extends Model
{
    protected $table = "dbo.title";

    protected $primaryKey = 'TitleID';

}

I can retrieve the contents of this model correctly when running $title = Title::all(); in Tinker.

I have set up a new relationship in Employee.php:

public function title()
{
    return $this->hasOne('App\Title', 'TitleID');
}

However, in Tinker (which I have restarted) when I run:

$employee = Employee::first();
$employee->title()->get();

It returns:

Illuminate\Database\Eloquent\Collection {#3027 all: [], }

What have I done to set up this relationship incorrectly?

2 answers

  • answered 2020-05-22 12:42 party-ring

    The issue was that because the primary key of the other table isn't id, it wasn't able to find the collection.

    However, according to the documentation, it reads:

    Additionally, Eloquent assumes that the foreign key should have a value matching the id (or the custom $primaryKey) column of the parent.

    So I assumed that because I set a custom $primaryKey value, it would intuitively be able to find it - however it seems the issue was to do with the local key's name breaking Eloquent's convention.

    I solved the issue by declaring both the foreign and local key respectively:

    public function title()
    {
        return $this->hasOne('App\Title', 'TitleID', 'TitleID');
    }
    

  • answered 2020-05-22 12:42 Yezan Rafed

    You just need to access the property title instead of calling title():

    $employee = Employee::first();
    $employee->title;