How to Use a One-to-One Relationship in Laravel

In this tutorial, we will explore how to implement a one-to-one relationship using Laravel Eloquent. The process is straightforward and involves adding a single line of code to each of the two related classes.

To establish a one-to-one relationship in Laravel Eloquent, we use the hasOne method in one class and the corresponding belongsTo method in the other class. This creates a direct association between the entities, allowing seamless access to related data.

To begin, let’s have a look at the database diagram below. It shows the two tables involved: “users” and “profiles”, that we will connect through an Eloquent relationship. As you can see, a profile has a user_id field which points to the id of its owner in the users table. As we will see later on, it requires very little code to support this relationship in Eloquent objects.

Visualization of the Relationship Between profiles and users in ERD (Entity Relationship Diagram)

Next, we will walk through the required steps for creating the essential migrations and models, establishing their relationships, and executing queries to retrieve and manipulate related data. By the end of this tutorial, you will have a solid understanding of how to use a one-to-one relationship in Laravel.

Let’s get started!

Step 1: Create a User Migration

To begin, let’s make sure we have the correct a migration for the “users” table. This migration is the same as the Laravel default users migration. Check if you already have it. If you do, you can skip this step. Otherwise you may simply run:

php artisan make:migration users

Copy the up() and down() methods, as shown below, into your users migration:

database/migrations/2014_10_12_000000_create_users_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('users');
    }
};

Step 2: Create a User Model With a hasOne Relation

Next, let’s edit Laravel’s default Models\User.php. If it doesn’t exists yet use the following command to create it:

php artisan make:model User

Next, we will add a profile() function to our class User, this defines a hasOne relationship with the Profile model, indicating that a user has one profile associated with them. Here’s an example of how the User model should look:

app/Models/User.php
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
}

Step 3: Create a Profile Migration

Now, let’s create a migration for the “profiles” table. This table will contain additional information specific to the user’s profile, like in our example, a column “bio” where a user’s biography can be added. Here’s an example of the “up” and “down” methods for the Profile migration:

database/migrations/2023_06_24_214940_create_profiles_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('profiles', function (Blueprint $table) {
            $table->id();
            $table->string('bio');
            $table->foreignIdFor(\App\Models\User::class)->constrained();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('profiles');
    }
};

Should you use a version older then Laravel 8 replace the up() with this version, slightly longer syntax, version:

database/migrations/2023_06_24_214940_create_profiles_table.php
Schema::create('profiles', function (Blueprint $table) {
    $table->id();
    $table->string('bio');
    $table->bigInteger('user_id')->unsigned();
    $table->foreign('user_id')->references('id')->on('users');
    $table->timestamps();
});

Step 4: Create a Profile Model With a belongsTo Relation

Next, let’s create a Profile model that corresponds to the “profiles” table by running:

php artisan make:model Profile

We will define a belongsTo relationship with the User model, indicating that a profile belongs to a user. Here’s an example of how the Profile model should look:

app/Models/Profile.php
use Illuminate\Database\Eloquent\Model;

class Profile extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

Step 5: Perform Queries

Now that we have set up the migrations and models, we can perform queries to retrieve and manipulate data using the one-to-one relationship. Here are a few examples of how you can use the relationship:

routes/web.php
Route::get('/hasone', function () {
    // Create a user
    $user = new User();
    $user->name = 'John Doe';
    $user->email = 'john@example.com';
    $user->password = bcrypt('password');
    $user->save();

    // Create a profile
    $profile = new \App\Models\Profile();
    $profile->bio = 'Lorem ipsum dolor sit amet.';
    $user->profile()->save($profile); // save it using the hasOne

    // Retrieve a user's profile (provided by hasOne)
    $user = User::find(1);
    $profile = $user->profile;
    dump($profile->attributesToArray());

    // Inverse: Retrieve a profile's user (provided by belongsTo)
    $profile = \App\Models\Profile::find(1);
    $user = $profile->user;
    dump($user->attributesToArray());
});

The result shows the relation works properly

Browser Showing Output of User and Profile From HasOne Relationship

Conclusion

In this tutorial, we have explored how to use a one-to-one relationship in Laravel. We covered the steps required to set up the necessary migrations, create models with the appropriate relationships, and perform queries to retrieve and manipulate related data.

Now that you have a solid understanding of one-to-one relationships in Laravel, you can start exploring where this relationship type might be applicable in your own projects. Consider scenarios where you need to associate a single record from one table to another, such as user profiles, settings, or preferences. Happy coding!

References:

Johan van den Broek

Johan is the creator of laracoding.com. As a child, he began tinkering with various programming languages, many of which have been long forgotten today. Currently, he works exclusively with PHP and Laravel, and his passion for programming remains to this day.

Leave a Reply

Your email address will not be published. Required fields are marked *

Recent Posts