Menggunakan Fungsi SQL di Active Record
Sebagian besar database SQL menyediakan fungsi untuk mengambil bagian dari sebuah tanggal. Misalnya, PostgreSQL menggunakan EXTRACT(DOW FROM date), dengan DOW berarti “day of the week” (hari dalam minggu), yang mengembalikan nilai dari 0 (Minggu) hingga 6 (Sabtu).
Misalkan ada model Task dengan kolom created_at. Tujuan kita adalah mengambil record yang dibuat hanya pada hari kerja. Kita akan memakai kemampuan query Active Record untuk melakukannya.
# app/models/task.rb
class Task < ApplicationRecord
scope :weekdays_only, -> { where("EXTRACT(DOW FROM created_at) BETWEEN 1 AND 5") }
end
Penjelasan:
-
EXTRACT(DOW FROM created_at): Mengambil hari dalam minggu dari timestampcreated_at. -
BETWEEN 1 AND 5: Membatasi pilihan hanya Senin sampai Jumat.
Menggunakan Method Date Ruby dengan Active Record
Jika Anda ingin hanya menggunakan method Date Ruby, Anda bisa mengubah kode untuk memfilter record setelah mengambilnya dari database, tetapi cara ini tidak efisien untuk dataset yang besar.
# app/models/task.rb
class Task < ApplicationRecord
def self.weekdays_only_ruby
all.select { |task| task.created_at.on_weekday? }
end
end
Penjelasan:
- Cara ini mengambil semua record dari database terlebih dahulu, lalu memfilternya dengan method Ruby
on_weekday?. -
task.created_at.on_weekday?: Mengonversi timestamp created_at menjadi objek Date Ruby dan memeriksa apakah itu hari kerja (Senin sampai Jumat).
Contoh Penggunaan:
Task.weekdays_only_ruby
Catatan: Pendekatan ini bisa tidak efisien karena mengambil semua record dari database terlebih dahulu, lalu memprosesnya di memori. Cara ini disarankan untuk dataset kecil. Jika Anda bekerja dengan dataset yang lebih besar, solusi SQL akan jauh lebih efisien.
Menggabungkan Kondisi dengan Active Record
Anda mungkin ingin memfilter record berdasarkan hari kerja sekaligus kondisi tertentu, seperti status. Ini bisa dilakukan dengan merangkai scope:
# app/models/task.rb
class Task < ApplicationRecord
scope :weekdays_only, -> { where.not("EXTRACT(DOW FROM created_at) IN (0, 6)") }
scope :completed, -> { where(status: 'completed') }
end
Contoh Penggunaan:
Task.weekdays_only.completed
Query di Zona Waktu yang Berbeda
Saat menangani zona waktu, pastikan timestamp created_at dikonversi dengan benar. Gunakan klausa AT TIME ZONE di SQL agar perbandingannya akurat.
# app/models/task.rb
class Task < ApplicationRecord
scope :weekdays_only_in_timezone, ->(timezone) {
where("EXTRACT(DOW FROM created_at AT TIME ZONE ?) BETWEEN 1 AND 5", timezone)
}
end
Contoh Penggunaan:
Task.weekdays_only_in_timezone('UTC')
Menangani Database Lain
Database SQL yang berbeda mungkin memakai fungsi yang berbeda untuk mengambil bagian tanggal:
- MySQL:
DAYOFWEEK(created_at) - SQLite:
strftime('%w', created_at)
Pastikan Anda menyesuaikan query dengan database yang digunakan:
# Example for MySQL
scope :weekdays_only, -> { where("DAYOFWEEK(created_at) BETWEEN 2 AND 6") }
Setelah menerapkan scope ini, query Task.weekdays_only akan menghasilkan kumpulan task yang hanya dibuat pada hari kerja. Berikut contohnya:
tasks = Task.weekdays_only
tasks.each do |task|
puts task.created_at
end
Output:
2024-08-26 10:30:00 UTC # Monday
2024-08-27 11:45:00 UTC # Tuesday
2024-08-28 09:00:00 UTC # Wednesday
Kesimpulan
Memfilter hasil Active Record agar hanya mencakup hari kerja cukup mudah dengan memanfaatkan fungsi SQL dan method Ruby untuk mengambil bagian dari tanggal.
Artikel lain yang mungkin Anda sukai:
Beekeeper Studio Adalah GUI Database Gratis & Open Source
Tool query & editor SQL terbaik yang pernah saya pakai. Semua yang saya butuhkan untuk mengelola database ada di sini. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio cepat, intuitif, dan mudah digunakan. Beekeeper mendukung banyak sekali database, dan berjalan mulus di Windows, Mac, dan Linux.
Apa Kata Pengguna Tentang Beekeeper Studio
"Beekeeper Studio benar-benar menggantikan alur kerja SQL lama saya. Cepat, intuitif, dan membuat kerja dengan database kembali menyenangkan."
"Saya sudah mencoba banyak GUI database, tetapi Beekeeper punya keseimbangan sempurna antara fitur dan kesederhanaan. Langsung jalan."