Eloquent ORM (Object-Relational Mapper) adalah fitur bawaan Laravel yang membuat interaksi dengan database menjadi jauh lebih mudah dan efisien. Jika Anda seorang developer Laravel, menguasai Eloquent adalah keharusan. Artikel ini akan membahas contoh penggunaan Eloquent ORM Laravel secara mendalam, mulai dari dasar hingga implementasi yang lebih kompleks. Kita akan menjelajahi bagaimana Eloquent membantu Anda bekerja dengan database tanpa harus menulis query SQL yang rumit. Siap? Mari kita mulai!
1. Apa Itu Eloquent ORM dan Mengapa Penting dalam Laravel?
Eloquent ORM adalah implementasi ActiveRecord yang memungkinkan Anda berinteraksi dengan database menggunakan model PHP. Bayangkan, daripada menulis kode SQL yang panjang dan sulit dibaca, Anda bisa menggunakan metode-metode yang disediakan Eloquent untuk melakukan operasi CRUD (Create, Read, Update, Delete) dengan mudah.
Mengapa Eloquent Penting?
- Kemudahan Penggunaan: Eloquent menyederhanakan interaksi database, mengurangi kebutuhan untuk menulis SQL yang kompleks.
- Keamanan: Eloquent membantu mencegah serangan SQL injection dengan otomatis meng-escape data.
- Readability: Kode menjadi lebih mudah dibaca dan dipahami karena menggunakan sintaks yang intuitif.
- Maintainability: Kode lebih mudah dipelihara karena perubahan pada skema database dapat diakomodasi dengan lebih mudah.
- Abstraction: Eloquent menyediakan lapisan abstraksi yang memungkinkan Anda untuk mengganti database dengan lebih mudah tanpa mengubah banyak kode.
Dengan menggunakan Eloquent, Anda bisa fokus pada logika aplikasi Anda dan membiarkan Eloquent mengurus detail interaksi dengan database.
2. Konfigurasi Database untuk Penggunaan Eloquent di Laravel
Sebelum memulai contoh penggunaan Eloquent ORM Laravel, pastikan Anda sudah mengkonfigurasi koneksi database Anda di file .env
. Laravel mendukung berbagai jenis database, termasuk MySQL, PostgreSQL, SQLite, dan SQL Server.
Berikut contoh konfigurasi untuk MySQL:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=nama_database_anda
DB_USERNAME=username_database_anda
DB_PASSWORD=password_database_anda
Ganti nilai-nilai di atas dengan informasi database Anda yang sebenarnya. Setelah konfigurasi selesai, Anda dapat menjalankan perintah php artisan migrate
untuk membuat tabel-tabel database berdasarkan migration yang telah Anda buat.
3. Membuat Model Eloquent: Dasar-Dasar dan Penamaan
Model Eloquent adalah representasi dari tabel database Anda. Untuk membuat model, Anda dapat menggunakan perintah Artisan:
php artisan make:model NamaModel
Contoh:
php artisan make:model Product
Perintah ini akan membuat file app/Models/Product.php
. Secara konvensi, nama model menggunakan singular (tunggal) dan huruf kapital di awal, dan berkorespondensi dengan nama tabel database yang plural (jamak) dan snake_case. Contoh: Model Product
diasumsikan berinteraksi dengan tabel products
.
Berikut adalah contoh kode model Product
:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Product extends Model
{
use HasFactory;
// Jika nama tabel Anda berbeda dari konvensi, Anda dapat menentukannya di sini.
// protected $table = 'products_list';
// Jika primary key Anda bukan 'id', Anda dapat menentukannya di sini.
// protected $primaryKey = 'product_id';
// Jika Anda tidak ingin timestamps (created_at dan updated_at) diurus, set ini ke false.
// public $timestamps = false;
// Daftar atribut yang boleh diisi (mass assignable). Penting untuk keamanan.
protected $fillable = [
'name',
'description',
'price',
'category_id'
];
// Daftar atribut yang tidak boleh diisi (guarded). Alternatif untuk fillable.
// protected $guarded = ['id'];
// Relasi dengan model Category
public function category()
{
return $this->belongsTo(Category::class);
}
}
Penjelasan:
use HasFactory;
: Menggunakan trait untuk factories (digunakan untuk seeding data).protected $fillable
: Menentukan atribut mana yang boleh diisi saat membuat atau memperbarui model secara massal (mass assignment). Penting untuk selalu menentukan$fillable
atau$guarded
untuk mencegah kerentanan mass assignment.protected $guarded
: Menentukan atribut mana yang tidak boleh diisi saat mass assignment.public function category()
: Mendefinisikan relasi “belongsTo” dengan modelCategory
.
4. Operasi CRUD dengan Eloquent: Membuat, Membaca, Mengupdate, dan Menghapus Data
Ini adalah jantung dari contoh penggunaan Eloquent ORM Laravel: melakukan operasi CRUD.
a. Membuat Data (Create)
Ada beberapa cara untuk membuat data baru:
-
Menggunakan
new
dansave()
:$product = new Product(); $product->name = 'Laptop Terbaru'; $product->description = 'Laptop dengan spesifikasi tinggi'; $product->price = 12000000; $product->category_id = 1; $product->save();
-
Menggunakan
create()
(Mass Assignment):$product = Product::create([ 'name' => 'Smartphone Unggulan', 'description' => 'Smartphone dengan kamera terbaik', 'price' => 8000000, 'category_id' => 2 ]);
*Pastikan Anda sudah mendefinisikan
$fillable
di model Anda jika menggunakancreate()
.
b. Membaca Data (Read)
Eloquent menyediakan berbagai metode untuk membaca data:
-
Mengambil semua data:
$products = Product::all();
-
Mengambil satu data berdasarkan ID:
$product = Product::find(1); // Mengembalikan null jika tidak ditemukan $product = Product::findOrFail(1); // Melempar exception ModelNotFoundException jika tidak ditemukan
-
Menggunakan
where()
untuk filter:$products = Product::where('category_id', 1)->get(); // Mengambil semua produk dengan category_id = 1 $product = Product::where('name', 'Laptop Terbaru')->first(); // Mengambil satu produk dengan nama 'Laptop Terbaru'
-
Menggunakan
firstOrFail()
:$product = Product::where('name', 'Laptop Terbaru')->firstOrFail(); // Melempar exception ModelNotFoundException jika tidak ditemukan
-
Menggunakan
count()
untuk menghitung jumlah data:$totalProducts = Product::count(); // Menghitung jumlah semua produk $totalProductsInCategory = Product::where('category_id', 1)->count(); // Menghitung jumlah produk dalam kategori 1
c. Mengupdate Data (Update)
Sama seperti membuat data, ada beberapa cara untuk mengupdate data:
-
Menggunakan
find()
dansave()
:$product = Product::find(1); if ($product) { $product->price = 13000000; $product->save(); }
-
Menggunakan
update()
(Mass Assignment):Product::where('category_id', 2)->update(['price' => 9000000]); // Mengupdate harga semua produk dengan category_id = 2
*Pastikan Anda sudah mendefinisikan
$fillable
di model Anda jika menggunakanupdate()
.
d. Menghapus Data (Delete)
-
Menggunakan
find()
dandelete()
:$product = Product::find(1); if ($product) { $product->delete(); }
-
Menggunakan
destroy()
:Product::destroy(1); // Menghapus produk dengan ID 1 Product::destroy([1, 2, 3]); // Menghapus produk dengan ID 1, 2, dan 3
-
Menghapus berdasarkan kondisi
where()
:Product::where('category_id', 3)->delete(); // Menghapus semua produk dengan category_id = 3
5. Relasi Antar Model (Relationships): One-to-One, One-to-Many, Many-to-Many
Eloquent ORM sangat kuat dalam menangani relasi antar tabel. Ini adalah bagian penting dari contoh penggunaan Eloquent ORM Laravel.
a. One-to-One (Satu ke Satu)
Contoh: Setiap User
memiliki satu Profile
.
Di model User
:
public function profile()
{
return $this->hasOne(Profile::class);
}
Di model Profile
:
public function user()
{
return $this->belongsTo(User::class);
}
b. One-to-Many (Satu ke Banyak)
Contoh: Setiap Category
memiliki banyak Product
.
Di model Category
:
public function products()
{
return $this->hasMany(Product::class);
}
Di model Product
:
public function category()
{
return $this->belongsTo(Category::class);
}
c. Many-to-Many (Banyak ke Banyak)
Contoh: Setiap Product
bisa memiliki banyak Tag
, dan setiap Tag
bisa dimiliki oleh banyak Product
. Ini memerlukan tabel perantara (pivot table) biasanya dinamakan product_tag
.
Di model Product
:
public function tags()
{
return $this->belongsToMany(Tag::class);
}
Di model Tag
:
public function products()
{
return $this->belongsToMany(Product::class);
}
Menggunakan Relasi:
Setelah mendefinisikan relasi, Anda bisa menggunakannya seperti ini:
$category = Category::find(1);
$products = $category->products; // Mengambil semua produk yang termasuk dalam kategori 1
$product = Product::find(1);
$category = $product->category; // Mengambil kategori dari produk dengan ID 1
$user = User::find(1);
$profile = $user->profile; // Mengambil profile dari user dengan ID 1
6. Eager Loading: Meningkatkan Performa dengan Mengurangi Query Database
Eager loading adalah teknik untuk memuat relasi bersama dengan model utama dalam satu query database. Ini sangat penting untuk meningkatkan performa aplikasi Anda, terutama saat berurusan dengan relasi yang banyak. Ini adalah bagian penting dari contoh penggunaan Eloquent ORM Laravel, terutama saat performa jadi perhatian utama.
Contoh: Tanpa eager loading, jika Anda ingin menampilkan daftar produk beserta nama kategorinya, Anda mungkin akan melakukan ini:
$products = Product::all();
foreach ($products as $product) {
echo $product->name . ' - ' . $product->category->name . '<br>'; // Akan menjalankan 1 query untuk setiap produk!
}
Ini akan menghasilkan N+1 query problem (1 query untuk mengambil semua produk, dan N query tambahan untuk mengambil kategori masing-masing produk).
Dengan eager loading, Anda bisa melakukannya seperti ini:
$products = Product::with('category')->get();
foreach ($products as $product) {
echo $product->name . ' - ' . $product->category->name . '<br>'; // Hanya menjalankan 2 query (1 untuk produk, 1 untuk kategorinya)
}
Dengan menggunakan with('category')
, Anda memberitahu Eloquent untuk memuat relasi category
bersamaan dengan model Product
, sehingga hanya 2 query yang dijalankan.
Anda juga bisa melakukan eager loading dengan beberapa relasi sekaligus:
$products = Product::with(['category', 'tags'])->get();
7. Query Scopes: Menggunakan Kembali Logika Query yang Umum
Query scopes memungkinkan Anda untuk mendefinisikan logika query yang umum digunakan dalam model Anda dan menggunakannya kembali di berbagai tempat. Ini membantu menjaga kode Anda tetap DRY (Don’t Repeat Yourself).
a. Global Scopes:
Global scopes selalu diterapkan pada query untuk model tertentu.
Contoh: Jika Anda ingin selalu memfilter produk yang aktif, Anda bisa membuat global scope:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseDatabaseEloquentBuilder;
use IlluminateDatabaseEloquentScope;
class ActiveProductScope implements Scope
{
public function apply(Builder $builder, Model $model)
{
$builder->where('is_active', true);
}
}
// di model Product.php
use AppScopesActiveProductScope;
protected static function booted()
{
static::addGlobalScope(new ActiveProductScope);
}
Sekarang, setiap kali Anda melakukan query pada model Product
, hanya produk yang is_active
bernilai true
yang akan dikembalikan.
b. Local Scopes:
Local scopes hanya diterapkan saat Anda memanggilnya secara eksplisit.
Contoh: Membuat scope untuk mencari produk berdasarkan nama:
// Di model Product.php
public function scopeSearchByName(Builder $query, $name)
{
return $query->where('name', 'like', '%' . $name . '%');
}
// Penggunaan:
$products = Product::searchByName('Laptop')->get();
8. Accessors dan Mutators: Memodifikasi Atribut Model
Accessors dan mutators memungkinkan Anda untuk memodifikasi nilai atribut model saat diakses (accessor) atau disimpan (mutator). Ini berguna untuk memformat data, melakukan enkripsi/dekripsi, atau melakukan validasi.
a. Accessor:
Accessor memodifikasi nilai atribut saat diakses.
Contoh: Memformat harga produk untuk menampilkan mata uang:
// Di model Product.php
public function getFormattedPriceAttribute()
{
return 'Rp. ' . number_format($this->price, 0, ',', '.');
}
// Penggunaan:
$product = Product::find(1);
echo $product->formatted_price; // Akan menampilkan "Rp. 12.000.000"
b. Mutator:
Mutator memodifikasi nilai atribut saat disimpan.
Contoh: Mengenkripsi deskripsi produk sebelum disimpan ke database:
// Di model Product.php
public function setDescriptionAttribute($value)
{
$this->attributes['description'] = bcrypt($value);
}
// Saat menyimpan:
$product = new Product();
$product->description = 'Deskripsi yang akan dienkripsi';
$product->save(); // Deskripsi akan dienkripsi sebelum disimpan
9. Menggunakan Factories dan Seeders untuk Pengujian dan Pengembangan
Factories dan seeders adalah alat yang berguna untuk membuat data dummy untuk pengujian dan pengembangan. Factories menghasilkan data palsu, sementara seeders menggunakan factories untuk mengisi database dengan data.
a. Membuat Factory:
php artisan make:factory ProductFactory
Ini akan membuat file database/factories/ProductFactory.php
.
Contoh:
<?php
namespace DatabaseFactories;
use AppModelsProduct;
use IlluminateDatabaseEloquentFactoriesFactory;
class ProductFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Product::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->sentence(3),
'description' => $this->faker->paragraph,
'price' => $this->faker->numberBetween(1000000, 15000000),
'category_id' => 1, // Ganti dengan ID kategori yang valid
];
}
}
b. Membuat Seeder:
php artisan make:seeder ProductSeeder
Ini akan membuat file database/seeders/ProductSeeder.php
.
Contoh:
<?php
namespace DatabaseSeeders;
use AppModelsProduct;
use IlluminateDatabaseSeeder;
use DatabaseFactoriesProductFactory;
class ProductSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Product::factory()->count(50)->create(); // Membuat 50 produk dummy
}
}
c. Menjalankan Seeder:
php artisan db:seed --class=ProductSeeder
Atau, untuk menjalankan semua seeder:
php artisan db:seed
10. Soft Deletes: Menyimpan Catatan Penghapusan Data
Soft deletes memungkinkan Anda untuk menandai data sebagai terhapus tanpa benar-benar menghapusnya dari database. Ini berguna untuk audit trail atau untuk memulihkan data yang tidak sengaja terhapus.
Untuk mengaktifkan soft deletes, tambahkan trait SoftDeletes
ke model Anda:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentSoftDeletes;
class Product extends Model
{
use SoftDeletes;
// ...
}
Tambahkan juga kolom deleted_at
(timestamp) ke tabel Anda menggunakan migration:
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
use IlluminateDatabaseMigrationsMigration;
class AddDeletedAtToProductsTable extends Migration
{
public function up()
{
Schema::table('products', function (Blueprint $table) {
$table->softDeletes();
});
}
public function down()
{
Schema::table('products', function (Blueprint $table) {
$table->dropSoftDeletes();
});
}
}
Setelah itu, saat Anda memanggil delete()
, data tidak akan dihapus secara permanen, tetapi kolom deleted_at
akan diisi dengan timestamp saat penghapusan dilakukan.
Mengambil Data yang Terhapus (Soft Deleted):
-
Mengambil hanya data yang tidak terhapus (default):
$products = Product::all(); // Hanya mengambil produk yang deleted_at null
-
Mengambil semua data, termasuk yang terhapus:
$products = Product::withTrashed()->get();
-
Mengambil hanya data yang terhapus:
$products = Product::onlyTrashed()->get();
Memulihkan Data yang Terhapus:
$product = Product::withTrashed()->find(1);
$product->restore(); // Memulihkan produk dengan ID 1
Menghapus Data Secara Permanen (Force Delete):
$product = Product::withTrashed()->find(1);
$product->forceDelete(); // Menghapus produk dengan ID 1 secara permanen
11. Pagination dengan Eloquent: Menampilkan Data dalam Halaman
Pagination adalah cara untuk membagi data yang banyak menjadi beberapa halaman yang lebih kecil dan mudah dikelola. Eloquent menyediakan metode paginate()
untuk memudahkan implementasi pagination.
Contoh:
$products = Product::paginate(10); // Membagi data produk menjadi halaman-halaman, dengan 10 produk per halaman
// Di view:
@foreach ($products as $product)
{{ $product->name }} <br>
@endforeach
{{ $products->links() }} // Menampilkan link pagination
$products->links()
akan menghasilkan HTML untuk link pagination yang dapat Anda sesuaikan sesuai kebutuhan. Anda juga dapat menggunakan simplePaginate()
jika Anda hanya membutuhkan link “Next” dan “Previous”.
12. Kesimpulan: Memaksimalkan Penggunaan Eloquent ORM untuk Pengembangan Laravel yang Efisien
Dalam artikel ini, kita telah membahas berbagai contoh penggunaan Eloquent ORM Laravel secara mendalam. Dari konfigurasi dasar hingga fitur-fitur canggih seperti relasi, eager loading, scopes, accessors/mutators, factories/seeders, soft deletes, dan pagination, Anda sekarang memiliki dasar yang kuat untuk mengembangkan aplikasi Laravel yang efisien dan mudah dipelihara.
Eloquent ORM adalah salah satu kekuatan utama Laravel, dan dengan menguasainya, Anda akan menjadi developer Laravel yang lebih produktif dan kompeten. Ingatlah untuk selalu mengikuti konvensi dan best practices untuk memastikan kode Anda tetap bersih, mudah dibaca, dan aman. Selamat mencoba dan semoga sukses!