Laravel Eloquent Relationships One to One
Laravel adalah kerangka kerja (framework) PHP yang populer untuk pengembangan web. Salah satu fitur andalannya adalah Eloquent ORM, yang memudahkan interaksi dengan database menggunakan objek-objek PHP. Dalam Eloquent, terdapat konsep “relationship” (hubungan) yang memungkinkan Anda untuk dengan mudah membangun hubungan antara model-model data dalam database.
Eloquent menyediakan beberapa jenis relationship yang dapat digunakan untuk menggambarkan hubungan antara model. Kali ini kita akan membahas mengenai salah satu relationship yaitu :
One-to-One
One-to-One adalah Relationship satu ke satu menghubungkan satu record dari model dengan satu record dari model lainnya. Misalnya, kita memiliki model “Customer” dan “Wallet”, dimana setiap customer hanya memiliki satu wallet, dan satu wallet hanya memiliki satu customer.
Sekarang kita coba membuat relationship one to one menggunakan eloquent di laravel.
LANGKAH 1 : Buat projek laravel dengan perintah :
composer create-project laravel/laravel nama_file_kalian
LANGKAH 2 : Membuat Model, Migration dan Seeder
Pertama, mari kita buat model “Customer” dan migration untuk tabel “customers”. Di terminal, masukkan perintah berikut:
php artisan make:model Customer -ms
Kedua, mari kita buat model “Wallets” dan migration untuk tabel “wallets”. Di terminal, masukkan perintah berikut:
php artisan make:model Wallet -ms
LANGKAH 3 : Mengatur isi atribut di migrations
Sekarang mari kita buka file migration di database\migrations\………_create_customers_table.php . Kita akan mengisi atribut apa saja yang ada di tabel customer dengan cara mengisi pad Schema::create
<?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('customers', function (Blueprint $table) {
$table->string('id')->nullable(false)->primary();
$table->string('name')->nullable(false);
$table->string('email')->nullable(false)->unique('customer_email');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('customers');
}
};
Lakukan hal yang sama pada tabel Wallet .
<?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('wallets', function (Blueprint $table) {
$table->integerIncrements('id');
$table->string('customer_id', 100)->nullable(false);
$table->bigInteger('amount')->nullable(false)->default(0);
$table->foreign('customer_id')->references('id')->on('customers');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('wallets');
}
};
LANGKAH 4 : Mendefinisikan Relasi One-to-One
Setelah kita memiliki tabel “customers” dan “wallets” yang diperlukan, kita perlu mendefinisikan relasi “one-to-one” di antara kedua model tersebut.
Buka file model “Customer” (app/Models/Customer.php
) dan tambahkan metode untuk mendefinisikan relasi "hasOne" dengan model "Wallet":
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
class Customer extends Model
{
use HasFactory;
protected $table = 'customers';
protected $primaryKey = 'id';
protected $keyType = 'string';
public $incrementing = false;
public $timestamps = false;
public function wallet(): HasOne
{
return $this->hasOne(Wallet::class, 'customer_id', 'id');
}
}
Pada bagian relasi “hasOne” dalam model Customer ini, kita mendefinisikan bahwa model Customer memiliki satu relasi terhadap model Wallet. Relasi ini didefinisikan dengan menggunakan metode “hasOne” dari Eloquent, yang menunjukkan bahwa setiap objek Customer akan berhubungan dengan satu objek Wallet.
Penghubung antara keduanya ditentukan oleh dua parameter. Pertama, kita menyebutkan model yang ingin kita hubungkan (dalam hal ini, model Wallet). Kemudian, kita menentukan nama kolom pada tabel Wallet yang akan menjadi referensi ke kolom “id” pada tabel Customer, yaitu “customer_id”.
Dengan menggunakan relasi “hasOne” ini, kita dapat dengan mudah mengakses data Wallet yang terkait dengan setiap Customer menggunakan metode “wallet()” pada objek Customer. Relasi ini memudahkan pengambilan data terkait antara dua model yang saling terkait dalam basis data.
selanjutnya buka file model “Wallet” (app/Models/Wallet.php
) dan tambahkan metode untuk mendefinisikan relasi "belongsTo" dengan model "Customer":
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Wallet extends Model
{
use HasFactory;
protected $table = 'wallets';
protected $primaryKey = 'id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
public function user(): BelongsTo
{
return $this->belongsTo(Customer::class, 'customer_id', 'id');
}
}
Pada model Wallet di atas, kita mendefinisikan relasi “belongsTo” dengan model Customer. Ini berarti setiap objek Wallet akan memiliki hubungan yang terikat dengan satu objek Customer. Relasi “belongsTo” ini memungkinkan setiap objek Wallet memiliki satu kunci asing (foreign key) yang menghubungkannya dengan kolom “id” pada tabel Customer.
Penghubung antara keduanya juga ditentukan oleh dua parameter. Pertama, kita menyebutkan model yang ingin kita hubungkan (dalam hal ini, model Customer). Selanjutnya, kita menentukan nama kolom pada tabel Wallet yang akan digunakan sebagai kunci asing (foreign key) yang merujuk ke kolom “id” pada tabel Customer, yaitu “customer_id”.
Dengan menggunakan relasi “belongsTo” ini, kita dapat dengan mudah mengakses data Customer yang terkait dengan setiap Wallet menggunakan metode “user()” pada objek Wallet. Relasi ini membantu dalam mengakses data terkait dari model Customer yang memiliki keterkaitan dengan model Wallet dalam database.
LANGKAH 5 : Tambahkan seeder
Untuk menguji relasi “one-to-one”, mari kita tambahkan beberapa data ke dalam tabel “customers” dan “wallets” melalui seeder. Buka file seeder DatabaseSeeder.php
di direktori database/seeders
dan panggil seeder CustomerSeeder
dan WalletSeeder
dalam method run()
:
<?php
namespace Database\Seeders;
// 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([
CustomerSeeder::class,
WalletSeeder::class,
]);
}
}
Sekarang kita buka file database/seeeders/CustomerSeeder.php
Tambahkan seeder untuk mengisi data pada tabel Customer
<?php
namespace Database\Seeders;
use App\Models\Customer;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class CustomerSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
Customer::create([
'id' => 'M123',
'name' => 'John Doe',
'email' => 'john.doe@example.com',
]);
}
}
Sekarang kita buka file database/seeeders/WalletSeeder.php
Tambahkan seeder untuk mengisi data pada tabel Wallet
<?php
namespace Database\Seeders;
use App\Models\Wallet;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class WalletSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
Wallet::create([
'customer_id' => 'M123', //sesuaikan dengan primary key customer
'amount' => 1000,
]);
}
}
Langkah 6: Menguji Relasi
Buat tes baru untuk menguji relasi dengan perintah:
php artisan make:test CustomerTest
Buka file CustomerTest.php
di direktori tests/Feature
dan gantilah kode dengan kode berikut:
<?php
namespace Tests\Feature;
use App\Models\Customer;
use Database\Seeders\CustomerSeeder;
use Database\Seeders\WalletSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class CustomerTest extends TestCase
{
public function testOneToOne()
{
$this->seed([CustomerSeeder::class , WalletSeeder::class]);
$customer = Customer::find('M123');
$this->assertNotNull($customer);
$wallet = $customer->wallet;
$this->assertNotNull($wallet);
$this->assertEquals(1000, $wallet->amount);
}
}
Untuk menjalankan Laravel Testing diatas kita bisa menjalankan perintah
php artisan test
Setelah itu maka terminal akan menunjukan apakah test code yang kita ditulis diatas berjalan atau tidak
Jika semuanya berjalan dengan baik, maka Anda telah berhasil membuat dan menguji relasi "one-to-one" antara model "Customer" dan "Wallet" di Laravel. Relasi ini memungkinkan Anda untuk mengakses data wallet dari customer dan sebaliknya dengan mudah. Selamat mencoba !!!👋👋