In this tutorial, we will learn one to one relationships with examples.
Let's assume we have two table users and a passport. So a user can have one passport number and passport number has one user.
For this tutorial, I'll use the already created Laravel project. If you have not set up you can follow the below link to install a fresh Laravel installation.
Table of Contents
Step 1. Create migration
For this tutorial, we will need two tables to set up the one to one relationship.
User
Passport
By default Laravel ships migration for user table
under database/migrations
and model file under app
directory. I will use the default migration file for this tutorial.
Now let's create a migration
and model
for passport
table.
php artisan make:migration create_passports_table
Now create a model for the passport table.
php artisan make:model Passport
Note: You can also run php artisan make:model Passport -m
to create migration and model together.
Now edit the passport migration file and add the following schema
#database/migrations/2019_09_17_174021_create_passport_table.php
public function up()
{
Schema::create('passport', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id');
$table->string('passport_number')->unique();
$table->timestamps();
});
}
and run the following command to create the table.
php artisan migrate
Step 2. Insert dummy data using Laravel factories
For this topic, we will use dummy data to test the one to one relationship. So, Let's quickly create a passport
factory and seeder class with the following command.
php artisan make:factory PassportFactory
php artisan make:seeder PassportSeeder
The above command will create a factory and a seeder class under the database/factory
and database/seeders
directory. Now edit the passport factory class and add the following class
#database/factories/PassportFactory.php
use App\Passport;
use Faker\Generator as Faker;
$factory->define(Passport::class, function (Faker $faker) {
return [
'user_id' => rand(1, 20),
'passport_number' => $faker->unique()->randomNumber($nbDigits = 9)
];
});
Next, edit the Passport seeder
class and add the following code.
#database/seeds/PassportSeeder.php
public function run()
{
factory('App\Passport', 20)->create();
}
The above code will create 20 unique passports number.
Next same thing for user table. Run the below command to create user factory and seeder class
php artisan make:factory UserFactory
php artisan make:seeder UserSeeder
#database/factories/UserFactory.php
$factory->define(User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
});
Don't forget to import user model
class. Now add the following code to UserSeeder class
#database/seeds/UserSeeder.php
public function run()
{
factory('App\User', 20)->create();
}
Once you are done with adding the above code. Now add the following code to the DatabaseSeeder
class
#database/seeds/DatabaseSeeder.php
public function run()
{
$this->call(UserSeeder::class);
$this->call(PassportSeeder::class);
}
Now run the below code to seed the database
php artisan db:seed
Step 3. Setting one to one relationship
Go to user model
and add the following code
public function passport()
{
return $this->hasOne('App\Passport');
}
Now to access the user's passport number. Go to your controller and add the following code in your function. Eg: my controller is HomeController and the function name is the index. import the user model and add the following code in your function.
$user = User::find(1);
dd($user->passport);
User::find(1)
will get all the user details associated with id 1. If you call the passport function it will display all the passport details associated with user id 1.
If you dump the eloquent query then you will get the following SQL query.
[
{
query: "select * from `users` where `users`.`id` = ? limit 1",
bindings: [
1
],
time: 2.51
},
{
query: "select * from `passports` where `passports`.`user_id` = ? and `passports`.`user_id` is not null limit 1",
bindings: [
1
],
time: 0.42
}
]
Step 4. Setting an inverse relationship
Go to passport model
and add the below code to set the inverse relationship
public function user()
{
return $this->belongsTo('App\User');
}
To access the user detail by passport number Go to your controller and add the below code.
$passport = App\Passport::find(1);
dd($passport->user);
The above query will fetch all the user detail associated with passport id 1.
If you dump the above eloquent query you will get the below SQL query.
[
{
query: "select * from `passports` where `passports`.`id` = ? limit 1",
bindings: [
1
],
time: 1.73
},
{
query: "select * from `users` where `users`.`id` = ? limit 1",
bindings: [
18
],
time: 0.94
}
]
Tip #1: To get passport details with the user in the same collection. You can use the laravel with()
function. for example
$passport = App\User::findOrFail(1)->with('passport')->first();
return $passport;
Tip #2: To dump the eloquent query you can use below code
\DB::enableQueryLog();
// your eloquent query
return \DB::getQueryLog();
Thank you for reading!