While designing database structure, you may get to know that some tables are related to one another. For example in a blog application, a user have many posts and post have many comments. In a MySQL database tables, we add one table's id to another table or create pivot table to create relationship between tables.
Laravel provides eloquent relationship which provides powerful query builders. In Laravel, eloquent relationships are defined in model classes. Laravel eloquent provides easy ways to create common relationships:
- one to one
- one to many
- many to many
- has one of many
- has one through
- has many through
- one to one polymorphic
- one to many polymorphic
- many to many polymorphic
In this article, we will discuss on how to create one to one eloquent relationship between two models. This is a very basic type of database relationship. For example, One User model is related with one Application model.
Example:
In this example, we assume that you have created fresh Laravel application. We also assume that you have confiured database connection.
Migration
We already have users migration class at database/migrations
directory, so we only need to create applications migration with following command:
php artisan make:migration create_applications_table
In the applications migration, we have defined the following fields. Notice we have added user_id(forengn_key) which relates with the id(local_key) field of users table. Below is the application migration fields:
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('applications', function (Blueprint $table) {
$table->id();
$table->integer('user_id')->unsigned();
$table->integer('number');
$table->boolean('status');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
In this example, we don't need to add or modify users migration. Below are the users migration field.
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();
});
Run the migrate command to create tables into database.
php artisan migrate
Model
Laravel model located at app/Models
directory. Create a Application model using following Artisan command.
php artisan make:model Application
Now, you need to create application method in User model.
There is already User model in the new Laravel application. Open User model and add application() method which will define relationship between User and Application model.
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* Get the application associated with the user.
*/
public function application()
{
return $this->hasOne(Application::class);
}
}
The eloquent will assume that you have user_id field in the applications table which relates to if field of users table. If you want to define other field than user_id into application, you may pass foreign_key as second argument. Suppose we have number field which is associated with id field of users table.
/**
* Get the application associated with the user.
*/
public function application()
{
return $this->hasOne(Application::class, 'number');
}
To define reverse relationship, i.e., if you already have application model and we want to find user model by relationship, we need to put user method into Application model.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Application extends Model
{
use HasFactory;
/**
* Get the user associated with the application.
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
Route
In routes/web.php file, we have added new route for relationship testing.
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ApplicationController;
Route::get('/application', [ApplicationController::class, 'index']);
Controller
As we have added route, also create ApplicationController with following command.
php artisan make:controller ApplicationController
Find application record related to user model
Open the controller at app/Http/Controllers/ApplicationController and create index method.
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$application = User::find(1)->application;
dd($application);
}
This will return application record with the user_id of 1.
Find user record that is belongs to application model
Now suppose you want to find user record by application model, i.e., reverse relationship, here is how to access user record.
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$user = Application::find(1)->user;
dd($user);
}
You can even get single value from the relationship, for example, you only want user email address of application, you may get only email address of application.
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$email = Application::find(1)->user->email;
dd($email);
}
I hope this will help you to understand one to one relationship.