A Laravel one-to-one relationship is a very basic type of relationship. An example of such a relationship could be a user-passport model. In this case, a user is only allowed to have one passport. Thus, we have a one-to-one relationship between users and passports.
To define a one-to-one relationship, you can use the hasOne() method in one class and the belongsTo() method in another class.
The hasOne() method defines a relationship that will return a single related model.
Here is the step-by-step guide:
Step 1: Creating a schema
Install and new Laravel project and configure your database in the .env file.
Go to the terminal and type the following command.
php artisan make:migration create_accounts_table
So, it will create one schema file in which we need to define the columns like the following.
<?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('accounts', function (Blueprint $table) { $table->id(); $table->integer('user_id'); $table->integer('account_number'); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('accounts'); } };
Type the following command in the terminal.
php artisan migrate
It will create the tables in the MySQL database.
Step 2: Seed the tables
We need to fill two tables.
- users
- accounts
Type the following two commands in your terminal.
php artisan make:seeder UsersTableSeeder php artisan make:seeder AccountsTableSeeder
We need to input some random values. So in UserTableSeeder.php, type the following code.
<?php namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; use Illuminate\Support\Str; class UsersTableSeeder extends Seeder { /** * Run the database seeds. */ public function run(): void { \DB::table('users')->insert([ 'name' => Str::random(10), 'email' => Str::random(10) . '@gmail.com', 'password' => bcrypt('secret'), ]); \DB::table('users')->insert([ 'name' => Str::random(10), 'email' => Str::random(10) . '@gmail.com', 'password' => bcrypt('secret'), ]); \DB::table('users')->insert([ 'name' => Str::random(10), 'email' => Str::random(10) . '@gmail.com', 'password' => bcrypt('secret'), ]); \DB::table('users')->insert([ 'name' => Str::random(10), 'email' => Str::random(10) . '@gmail.com', 'password' => bcrypt('secret'), ]); \DB::table('users')->insert([ 'name' => Str::random(10), 'email' => Str::random(10) . '@gmail.com', 'password' => bcrypt('secret'), ]); } }
For the AccountsTableSeeder.php file, type the following command.
<?php namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class AccountsTableSeeder extends Seeder { /** * Run the database seeds. */ public function run(): void { \DB::table('accounts')->insert([ 'user_id' => 1, 'account_number' => rand(100000000, 999999999) ]); \DB::table('accounts')->insert([ 'user_id' => 2, 'account_number' => rand(100000000, 999999999) ]); \DB::table('accounts')->insert([ 'user_id' => 3, 'account_number' => rand(100000000, 999999999) ]); \DB::table('accounts')->insert([ 'user_id' => 4, 'account_number' => rand(100000000, 999999999) ]); \DB::table('accounts')->insert([ 'user_id' => 5, 'account_number' => rand(100000000, 999999999) ]); } }
Add the following code in the DatabaseSeeder.php file.
<?php namespace Database\Seeders; use App\Models\User; // use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. */ public function run(): void { $this->call(UsersTableSeeder::class); $this->call(AccountsTableSeeder::class); } }
Type the following cmd in your terminal.
php artisan db:seed
If you go to the database, you will see that the Tables are filled with fake values.
Here is the accounts table:
Here is the users table:
Step 3: Define a one-to-one relationship.
Make one model called Account.php by typing this command.
php artisan make:model Account
In the User.php file, write the following function to define the relationship with the Account model.
public function account() { return $this->hasOne('\App\Models\Account'); }
To interact with the database, we need Laravel to provide one command-line interface called Tinker.
To boot up, the tinker hit the following command.
php artisan tinker
Type the following in the tinker.
$account = User::find(1)->account;
It will display the account details concerning user 1. So one-to-one relationship.
One user has only one single account. Eloquent determines a foreign key of a relationship based on a model name.
In this case, the Account model is automatically assumed to have the user_id foreign key.
If you wish to override this convention, you can pass the second argument to the hasOne method.
return $this->hasOne('App\Account', 'foreign_key');
Define an Inverse Of The Relationship
We can access an Account model from the User. Now, let’s define a relationship on an Account model that will allow us to obtain a User who owns an account.
We can determine the inverse of the hasOne relationship using the belongsTo method.
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Account extends Model { use HasFactory; public function user() { return $this->belongsTo('\App\Models\User'); } }
Eloquent will try to match a user_id from an Account model to an id on the User model in the example above.
An Eloquent ORM determines a default foreign key name by examining the name of a relationship method and suffixing the method name with _id.
However, if a foreign key on the Account model is not a user_id, you may pass the custom key name as the second argument to a belongsTo method.
That’s it.
abc
belongsTo