alshamsan
1 week ago

Error setting up One-to-Many relationship with custom foreign key

Posted 1 week ago by alshamsan

Issue

I am trying to set up a One-to-Many relationship between Country and User models, using a custom foreign key, instead of the conventional country_id column (users->country references countries->code).

Consider the following tables:

countries table:

| id | name         | code | language |
|----|--------------|------|----------|
| 1  | Canada       | ca   | English  |
| 2  | India        | in   | Hindi    |
| 3  | France       | fr   | French   |

users Table:

| id | name         | email           | country |
|----|--------------|-----------------|---------|
| 1  | Craig Harris | [email protected] | ca      |
| 2  | Tracy Hunt   | [email protected] | fr      |
| 3  | Lalita Gopal | [email protected] | in      |

How can I tell laravel to reference users->country to countries->code and be able to load the Country model of of the User? Something similar to the below:

How i want to use it is like this:

{{ $user->country->name }}

This is my attempt:

Migrations

Users Table Migration:

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->string('password');
    $table->string('country');
    $table->foreign('country')->references('code')->on('countries')->onUpdate('cascade');
    $table->timestamps();
});

Countries Table Migration:

Schema::create('countries', function (Blueprint $table) {
    $table->id();
    $table->string('code')->unique();
    $table->string('name');
    $table->string('language');
    $table->timestamps();
});

Models

User Model User.php

public function country()
{
    return $this->belongsTo(Country::class, 'country', 'code');
}

Country Model Country.php

public function users()
{
    return $this->hasMany(User::class, 'country', 'code');
}

Note: I used a custom foreign_key and local_key as I understood from the docs here.

View & Rote

Route file web.php

Route::get('/', function () {
    $users = User::with('country')->paginate(10);
    return view('users.index', ['users' => $users]);
});

my view file users/index.blade.php

<ul>
    @foreach ($users as $user)
    <li>{{ $user->country->name }}</li>
    @endforeach
</ul>

Error

I get the following error:

Trying to get property 'name' of non-object (View: ... /views/users/index.blade.php)

What am I doing wrong? :/

Please sign in or create an account to participate in this conversation.