CRUD merupakan singkatan dari create, read, update, dan delete, yaitu empat operasi dasar yang mencakup seluruh kebutuhan membaca dan mengubah data pada aplikasi biasa. Topik ini membahas keempat operasi tersebut menggunakan Eloquent pada aplikasi catatan, mulai dari create() dan firstOrCreate(), pencarian dengan find() dan findOrFail(), pembaruan melalui save() maupun update(), sampai delete(). Setiap operasi dijalankan langsung melalui Tinker dengan data contoh yang sama, yaitu satu catatan berjudul “Nota rapat tim”, sehingga keluarannya dapat direproduksi ulang dengan hasil yang identik.
Membuat data dengan create#
Metode create() menerima satu array atribut lalu langsung menyimpannya sebagai baris baru, kemudian mengembalikan objek model yang sudah memuat nilai lengkap beserta id barisnya. Karena penyimpanan dilakukan melalui pengisian massal, hanya atribut yang terdaftar pada $fillable yang diterima. Contoh berikut membuat satu catatan pada kategori Kerja, dan firstOrCreate() pada kategori menjamin pemanggilan ulang tidak menambah duplikasi kategori.
# membuat catatan baru dengan mass assignment
cd ~/aplikasi-catatan
php artisan tinker --execute='
use App\Models\Category;
use App\Models\Note;
Note::where("judul", "Nota rapat tim")->delete();
$kerja = Category::firstOrCreate(["nama" => "Kerja"]);
$nota = Note::create([
"judul" => "Nota rapat tim",
"isi" => "Mencatat poin pembahasan dan pembagian tugas rapat tim.",
"category_id" => $kerja->id,
]);
echo $nota->judul . PHP_EOL;
echo $nota->isi . PHP_EOL;
'Nota rapat tim
Mencatat poin pembahasan dan pembagian tugas rapat tim.Baris pertama pada blok menghapus sisa catatan dengan judul yang sama dari eksekusi sebelumnya, sehingga perintah ini aman dijalankan berulang kali tanpa menumpuk data. Objek yang dikembalikan create() sudah lengkap, dan atribut id-nya dapat langsung digunakan untuk operasi berikutnya tanpa query tambahan.
Mencegah duplikasi dengan firstOrCreate#
Metode firstOrCreate() mencari baris sesuai atribut yang diberikan, lalu membuatnya hanya apabila belum ada. Bentuk pemanggilannya menerima dua array, yaitu array pencarian dan array atribut tambahan untuk pembuatan. Metode ini menghasilkan keadaan akhir yang sama pada pemanggilan pertama maupun pemanggilan berikutnya, sehingga cocok untuk data yang harus selalu tersedia seperti kategori bawaan.
# firstOrCreate tidak menduplikasi baris yang sudah ada
cd ~/aplikasi-catatan
php artisan tinker --execute='
use App\Models\Category;
$a = Category::firstOrCreate(["nama" => "Kerja"]);
$b = Category::firstOrCreate(["nama" => "Kerja"]);
echo ($a->id === $b->id ? "id sama" : "id beda") . PHP_EOL;
echo Category::where("nama", "Kerja")->count() . PHP_EOL;
'id sama
1Kedua pemanggilan mengembalikan objek dengan id yang sama, dan jumlah baris kategori Kerja tetap satu. Apabila pemanggilan pertama tidak menemukan barisnya, metode tersebut membuatnya dan mengembalikan objek baru, sedangkan pemanggilan berikutnya cukup mencari dan mengembalikan baris yang sudah ada.
Mencari data dengan find dan findOrFail#
Metode find() mengambil satu baris berdasarkan primary key dan mengembalikan objek model, atau null apabila baris tersebut tidak ada. Sebaliknya, findOrFail() melemparkan error ModelNotFoundException ketika barisnya tidak ditemukan, sehingga cocok untuk kasus yang pemrosesannya tidak mungkin dilanjutkan tanpa data tersebut.
# mencari catatan dengan find dan findOrFail
cd ~/aplikasi-catatan
php artisan tinker --execute='
use App\Models\Note;
$id = Note::where("judul", "Nota rapat tim")->value("id");
echo Note::find($id)->judul . PHP_EOL;
var_dump(Note::find(99999));
try {
Note::findOrFail(99999);
} catch (Illuminate\Database\Eloquent\ModelNotFoundException $e) {
echo $e->getMessage() . PHP_EOL;
}
'Nota rapat tim
NULL
No query results for model [App\Models\Note] 99999Keluaran tersebut memperlihatkan perbedaan kedua metode pada baris yang tidak ada. find(99999) mengembalikan NULL tanpa pesan apa pun, sedangkan findOrFail(99999) menghentikan alur dengan pesan yang menyebutkan model dan primary key yang tidak ditemukan. Pencarian dengan kondisi lain dapat menggunakan where() diikuti first(), misalnya Note::where("judul", "Nota rapat tim")->first().
Memperbarui data#
Pembaruan dapat dilakukan dengan dua cara. Cara pertama mengambil objek model, mengubah propertinya satu per satu, lalu memanggil save() untuk menuliskan perubahannya ke database.
# memperbarui satu atribut melalui save()
cd ~/aplikasi-catatan
php artisan tinker --execute='
use App\Models\Category;
use App\Models\Note;
$nota = Note::firstOrCreate(
["judul" => "Nota rapat tim"],
["isi" => "Mencatat poin pembahasan dan pembagian tugas rapat tim.", "category_id" => Category::firstOrCreate(["nama" => "Kerja"])->id]
);
$nota->isi = "Isi nota diperbarui setelah rapat.";
$nota->save();
echo Note::where("judul", "Nota rapat tim")->value("isi") . PHP_EOL;
'Isi nota diperbarui setelah rapat.Cara kedua memanggil update() dengan satu array berisi beberapa atribut sekaligus, yang juga merupakan bentuk pengisian massal. Metode ini menggabungkan perubahan properti dan save() dalam satu pemanggilan, sehingga lebih ringkas ketika atribut yang berubah lebih dari satu.
# memperbarui beberapa atribut sekaligus dengan update()
cd ~/aplikasi-catatan
php artisan tinker --execute='
use App\Models\Category;
use App\Models\Note;
$belajar = Category::firstOrCreate(["nama" => "Belajar"]);
$nota = Note::where("judul", "Nota rapat tim")->first();
$nota->update([
"isi" => "Poin rapat dirangkum ulang.",
"category_id" => $belajar->id,
]);
echo Note::where("judul", "Nota rapat tim")->value("isi") . PHP_EOL;
echo Note::where("judul", "Nota rapat tim")->first()->category->nama . PHP_EOL;
'Poin rapat dirangkum ulang.
BelajarKeluaran kedua dibaca melalui $nota->category->nama, yaitu relasi milik model Note yang memetakan kolom category_id menjadi nama kategorinya. Nilai category_id yang baru pun langsung tercermin pada nama kategori yang dikembalikan relasi tersebut.
Aturan mass assignment dan MassAssignmentException#
Pengisian massal (mass assignment) hanya menerima atribut yang terdaftar pada $fillable. Pada perilaku bawaan, atribut di luar daftar tersebut dibuang tanpa pemberitahuan, sehingga kesalahan penulisan nama atribut tidak menimbulkan pesan apa pun dan data yang hilang baru ketahuan dari isi tabel. Laravel menyediakan pengetatan berupa Model::preventSilentlyDiscardingAttributes(true), yang mengubah perilaku bawaan itu menjadi error MassAssignmentException setiap kali ada atribut yang dibuang.
# mengetatkan aturan mass assignment lalu mencoba atribut di luar fillable
cd ~/aplikasi-catatan
php artisan tinker --execute='
use App\Models\Note;
use Illuminate\Database\Eloquent\Model;
Model::preventSilentlyDiscardingAttributes(true);
try {
Note::create(["judul" => "Nota rapat tim", "penulis" => "Ali"]);
} catch (Illuminate\Database\Eloquent\MassAssignmentException $e) {
echo $e->getMessage() . PHP_EOL;
}
'Add fillable property [penulis] to allow mass assignment on [App\Models\Note].Pesan error tersebut secara eksplisit menyebut atribut yang ditolak dan model yang bersangkutan, sehingga perbaikannya jelas, yaitu mendaftarkan penulis pada $fillable atau menghapus atribut itu dari array. Pengaturan preventSilentlyDiscardingAttributes() berlaku per proses, sehingga pemanggilan pada contoh di atas tidak mengubah perilaku aplikasi secara permanen.
Menghapus data#
Penghapusan dilakukan dengan mengambil objek model lalu memanggil delete() pada objek tersebut. Eloquent menjalankan pernyataan DELETE untuk baris yang bersangkutan, sedangkan alternatif tanpa pengambilan objek adalah pemanggilan delete() pada query, misalnya Note::where("judul", "Nota rapat tim")->delete(), yang menghapus seluruh baris hasil query tersebut sekaligus.
# menghapus catatan dan memeriksa hasilnya
cd ~/aplikasi-catatan
php artisan tinker --execute='
use App\Models\Category;
use App\Models\Note;
$kerja = Category::firstOrCreate(["nama" => "Kerja"]);
Note::firstOrCreate(
["judul" => "Nota rapat tim"],
["isi" => "Mencatat poin pembahasan dan pembagian tugas rapat tim.", "category_id" => $kerja->id]
);
$nota = Note::where("judul", "Nota rapat tim")->first();
$nota->delete();
echo Note::where("judul", "Nota rapat tim")->count() . PHP_EOL;
'0Blok di atas menyiapkan kembali catatan contoh sebelum menghapusnya, sehingga keluaran nol selalu diperoleh pada eksekusi ulang. Dengan berakhirnya bagian ini, keempat operasi CRUD telah dijalankan pada satu data contoh yang sama, yaitu dibuat, dibaca, diperbarui dua kali, dan dihapus.
Kesalahan umum#
Kesalahan pertama adalah memanggil metode pada hasil find() yang ternyata NULL, yang berujung pada error “Call to a member function delete() on null”. Perbaikannya adalah menggunakan findOrFail() ketika baris yang dicari memang wajib ada, atau memeriksa null terlebih dahulu sebelum melanjutkan.
Kesalahan kedua adalah mencoba memperbarui hasil get() secara massal, misalnya Note::where(...)->get()->update(...). Metode get() mengembalikan collection, bukan query, sehingga update() tidak tersedia padanya. Jalankan pembaruan langsung pada query dengan Note::where(...)->update([...]) atau lakukan perulangan pada collection sambil memanggil update() per objek.
Kesalahan ketiga adalah mengubah properti model lalu lupa memanggil save(). Perubahan hanya berada di memori sehingga tampak berhasil di layar tetapi tidak pernah tertulis ke database. Gunakan update() yang menuliskannya sekaligus apabila kebiasaan ini sering terjadi.
Ringkasan#
create()menyimpan baris baru melalui pengisian massal, sedangkanfirstOrCreate()mencari baris terlebih dahulu dan membuatnya hanya apabila belum ada.find()mengembalikan objek atauNULL, sedangkanfindOrFail()melemparkanModelNotFoundExceptiondengan pesan yang menyebut model dan primary key yang tidak ditemukan.- Pembaruan dilakukan melalui
save()setelah mengubah properti atau melaluiupdate()yang menerima beberapa atribut sekaligus, dan penghapusan melaluidelete()pada objek maupun pada query. - Atribut di luar
$fillabledibuang tanpa pemberitahuan pada perilaku bawaan, danModel::preventSilentlyDiscardingAttributes(true)mengubahnya menjadi errorMassAssignmentException.
Referensi#
- Eloquent: Getting Started — Laravel — Dokumentasi resmi operasi insert, update, delete, dan aturan mass assignment pada model.