DEV Community

Cover image for How to create a One-To-One relationship in Laravel?
Mahmoud Adel
Mahmoud Adel

Posted on • Originally published at laravelspa.site on

How to create a One-To-One relationship in Laravel?

One-to-One relationships are the simplest type of relationship offered by Laravel. They join two tables such that one row in the first table is associated with only one row in the other table, or the same table.

laravel one to one relationship

To see this in action, we'll start by creating a content management system.

To see this in action, let's start by creating a content management system. Let's say each user has their own single profile. In some cases, you can store all profile information in the Users table. However, this is not ideal.

In our example, we want to create a separate table for personal profiles. This will allow us to transfer a profile from one user to another easily if we need to.

By default, the Users table exists in Laravel. The columns that it contains do not matter for this example.

  • Let's say we have a users table with the following columns:
Schema::create('users', method (Blueprint $table) {
  $table->id();
  $table->string('username');
  $table->string('email')->unique();
  $table->timestamps();
});
Enter fullscreen mode Exit fullscreen mode
  • We edit the User.php file.
protected $fillable = ['username'];
Enter fullscreen mode Exit fullscreen mode
  • We create Profile Model with its table.
php artisan make:model Profile -m
Enter fullscreen mode Exit fullscreen mode

In a one-to-one relationship, we have the freedom to choose one of these two methods to establish the relationship:

  • Add user_id in the profiles table.
  • Add profile_id in the users table.

Usually, the column that joins the two tables is added to the second table. So, we will add it to the profiles table as follows:

Schema::create('profiles', method (Blueprint $table) {
  $table->id();
  $table->string('firstname');
  $table->string('lastname');
  $table->string('birthday');
  $table->foreignId('user_id')->constrained();
  $table->timestamps();
});
Enter fullscreen mode Exit fullscreen mode
  • We edit the Profile.php file.
protected $fillable = [
  'user_id',
  'firstname',
  'lastname',
  'birthday'
];
Enter fullscreen mode Exit fullscreen mode
  • Let's run this command to update the database.
php artisan migrate
Enter fullscreen mode Exit fullscreen mode
  • Let's go to the User.php file to define the relationship.
public method profile() {
    return $this->hasOne(Profile::class);
}
Enter fullscreen mode Exit fullscreen mode

Let's see how the hasOne() method works.
This method is used to save the id of the related model in the foreign key column of the parent model.

$this->hasOne(Profile::class,
  'user_id' // foreignKey By Default Parent Model + Promary Key
  'id' // localKey => Primary Key In Parent Table By Default is Id
);
Enter fullscreen mode Exit fullscreen mode
  • Let's go to the Profile.php file to define the inverse relationship.
public method user() {
    return $this->belongsTo(User::class);
}
Enter fullscreen mode Exit fullscreen mode

Let's find out how the belongsTo() method works.
This method is used to save the id of the parent model in the primary key column of the related model.

$this->belongsTo(User::class,
  'user_id' // foreignKey By Default Parent Model + Promary Key
  'id' // OwnerKey By Default Id
);
Enter fullscreen mode Exit fullscreen mode

Let's say you want to name the relationship something like admin, we need to add the foreignKey property to the relationship method.

public method admin() {
    return $this->belongsTo(User::class, 
      'user_id' // You must add foreignKey
    );
}
Enter fullscreen mode Exit fullscreen mode

The foreignKey property is used to specify the name of the column in the child model that is used to reference the parent model.

If you do not add the foreignKey property to the relationship method when changing the relationship name, you will see the following error:
Attempt to read property X on null

  • You can find the repo of this series on github here.

Top comments (0)