Secara default, Eloquent yang ada di Laravel berasumsi bahwa setiap table yang mereka tuju memiliki timestamps field, dalam hal ini adalah created_at
dan updated_at
. Namun apa jadinya jika aplikasi yang sedang kamu kembangkan adalah existing apps dengan bawaan database-nya masing-masing.
Laravel memberikan kebebasan penggunanya dalam menyesuaikan segala kondisi yang mereka hadapi, dalam hal ini adalah ketika berinteraksi waktu menggunakan Eloquent. Berikut adalah tips mengelola tanggal timestamps di Laravel.
Baca Juga: Aplikasi E-Commerce Laravel 6 #14: Kelola Pesanan (Admin) & Broadcast Resi
Disable Timestamps
Jika rancangan database kamu memiliki struktur tanpa timestamps untuk mencatat riwayat kapan data tersebut disimpan, maka ketika proses query menggunakan Eloquent, seperti Model::create($data)
dilakukan, secara otomatis akan memberikan feedback berupa error karena satu kerangka atau bagian dari proses tersebut tidak dikenali, dalam hal ini adalah column created_at
dan updated_at
.
Adapun cara untuk menonaktifkan proses tersebut adalah dengan menambahkan property berikut ini di dalam model atau Eloquent terkait.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public $timestamps = false;
}
Mengganti Nama Field Timestamps
Kasus berikutnya adalah ketika nama column untuk mencatat riwayat data berbeda dengan nama column yang sudah dikenali oleh Laravel secara default. Misalnya saja kamu sedang mengerjakan aplikasi yang sudah berjalan dan struktur database sebelumnya menggunakan nama date_created
dan date_updated
, maka ada dua cara untuk memberi tahu Laravel column mana yang sebaiknya dituju. Pertama untuk best practice-nya adalah dengan menambahkan kedua baris code berikut di dalam Eloquent atau model terkait
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
const CREATED_AT = 'create_time';
const UPDATED_AT = 'update_time';
}
Adapun cara kedua yang sedikit lebih bertele-tele adalah dengan men-disable timestamps kemudian mendeteksi event creating
dan updating
untuk memanipulasi column date_created
dan date_updated
, sehingga code-nya menjadi
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
class Post extends Model
{
public $timestamps = false;
protected static function boot()
{
parent::boot();
static::creating(function($post) {
$post->date_created = Carbon::now();
$post->date_updated = Carbon::now();
});
static::updating(function($post) {
$post->date_updated = Carbon::now();
});
}
}
Menampilkan Timestamps Pivot Table Many-to-Many
Pivot table yang dihasilkan dari relasi antar table akan menampilkan key yang saling terhubung tanpa dilengkapi dengan timestamps atau kapan data relasi tersebut ditambahkan. Misanya kita memiliki 3 buah table dengan struktur sebagaimana gambar dibawah ini
Adapun relasinya dari Post.php
menggunakan belongsToMany
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $guarded = [];
public function category()
{
return $this->belongsToMany(Category::class);
}
}
Kemudian tambahkan data baru yang saling berelasi, saya asumsikan di-table posts
dan categories
sudah terdapat 1 buah record, maka kita akan menambahkan datanya dengan code
$post = \App\Post::first();
$post->category()->attach(1);
Maka sebuah record baru akan tercipta di dalam table category_post
. Apabila data tersebut kita load menggunakan code.
$post = \App\Post::with(['category'])->first();
return $post;
Hasil yang akan ditampilkan adalah data utama beserta relasinya dalam hal ini adalah category dan diikuti dengan pivot masing-masing data.
Lalu pertanyaannya bagaimana cara menampilkan timestamps dari pivot table-nya? Caranya mudah, modifikasi relasinya dari file Post.php
menjadi
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $guarded = [];
public function category()
{
return $this->belongsToMany(Category::class)->withTimestamps();
}
}
Sehingga sturktur data yang dihasilkan akan terlihat seperti gambar di bawah ini.
Order By Menggunakan Timestamps
Ada beragam cara dalam mengurutkan data menggunakan Timestamps di Laravel, cara paling klasik adalah dengan membuat query .
$posts = Post::orderBy('created_at', 'DESC')->get();
Tahukah anda bahwa Laravel dalam hal ini Eloquent sudah menyediakan sebuah fungsi untuk mengambil data dengan mengurutkan data secara ringkas. Jika query diatas di-konversi maka singkatnya bisa menggunakan cara berikut.
$post = \App\Post::latest()->get();
Lalu bagaimana jika ingin menggunakan ascending? Tenang, Eloquent juga menyediakan fungsinya lainnya dengan cara
$post = \App\Post::oldest()->get();
Apabila kita ingin memilih column, dalam hal ini misalnya menggunakan updated_at
, caranya bagaimana? Cukup mudah, karena cukup memasukkan nama colum-nya sebagai parameter. Misalnya
$post = \App\Post::with(['category'])->oldest('updated_at')->get();
Update Data Tanpa Mengubah Value Updated_at
Jika kita terjebak dalam sebuah kondisi dimana harus mengubah data tanpa memperbaharui value dari updated_at
, maka Eloquent juga menawarkan solusinya tersendiri. Sebagaimana yang kita ketahui bahwa Eloquent akan secara otomatis memperbaharui updated_at
apabila terjadi perubahan data dari sebuah records.
Singkatnya, cara ini hampir sama dengan materi pertama yakni dengan men-disable timestamps. Hanya saja proses disable timestamps kita lakukan saat proses update berlangsung. Adapun query-nya akan terlihat seperti berikut
$post = \App\Post::with(['category'])->oldest('updated_at')->first();
$post->name = 'Tips Mengelola Tanggal Timestamps di Laravel';
$post->timestamps = false;
$post->save();
Baca Juga: 7 Tips Cara Cepat Belajar Bahasa Pemrograman
Pendekatan Touch Updated_at
Programmer itu banyak masalahnya, misalnya ketika sebuah aplikasi sedang berjalan dan dibutuhkan pembaharuan hanya pada column updated_at
tanpa mengubah value dari data lainnya. Maka cara pertama yang biasanya dilakukan adalah
$post = \App\Post::first();
$post->update(['updated_at' => now()]);
Alih-alih menggunakan cara di atas, Laravel menyediakan cara yang lebih sederhana dengan menggunakan fungsi touch()
, sehingga codingan-nya menjadi
$post = \App\Post::first();
$post->touch();
Contoh kasus yang lainnya adalah memperbaharui updated_at
beserta parent-nya, misalnya saja dari case yang kita gunakan adalah posts
merupakan child dari users
, apabila data posts diubah maka secara otomatis juga meng-update column updated_at
dari users.
Pendekatan yang bisa kita lakukan adalah mendefinisikan relasi posts ke user, kemudian menambahkan property $touches
.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $guarded = [];
protected $touches = ['user'];
public function user()
{
return $this->belongsTo(User::class);
}
}
Apabila kita membuat query untuk meng-update data posts maka secara otomatis updated_at
dari user yang terakait dengan post tersebut akan diperbaharui.
$post = \App\Post::with(['user'])->oldest('updated_at')->first();
$post->touch();
Comments