Rails adalah framework yang seluruh kodenya ditulis dengan Ruby, sehingga sebagian besar perilakunya dapat dijelaskan dengan keterampilan yang sudah dibangun sepanjang jalur ini. Topik ini membentuk mental model tentang prinsip convention over configuration, konvensi penamaan tunggal dan jamak, serta pemetaan pola model-view-controller ke kelas, modul, dan blok (block). Setelah topik ini selesai, berkas kode Rails dapat dibaca sebagai kode Ruby biasa yang mengikuti sejumlah aturan penamaan.
Konfigurasi versus konvensi#
Banyak framework meminta pengembang mendeskripsikan sambungan antarbagian melalui berkas konfigurasi, misalnya alamat mana yang ditangani berkas mana dan kelas mana yang menyimpan data ke tabel mana. Rails mengambil jalan sebaliknya, yaitu menetapkan struktur direktori dan aturan penamaan yang sama untuk semua aplikasi. Nama berkas menentukan perilaku, bukan berkas konfigurasi. Berkas app/models/catatan.rb yang berisi kelas Catatan otomatis diperlakukan sebagai model untuk tabel catatans, berkas app/controllers/catatans_controller.rb otomatis dikenali sebagai controller, sedangkan config/routes.rb menjadi satu-satunya tempat pencocokan permintaan (request) dinyatakan.
Prinsip ini dikenal sebagai convention over configuration, yakni keputusan teknis yang berulang telah ditetapkan sebelumnya sehingga tidak perlu ditulis ulang di setiap proyek. Konfigurasi tetap tersedia, tetapi posisinya berubah, yaitu hanya diperlukan apabila perilaku yang diinginkan berbeda dari kesepakatan bawaan. Konsekuensinya nyata ketika proyek dibaca ulang, karena dua aplikasi Rails yang berbeda memiliki peta direktori yang nyaris identik sehingga kode proyek lain dapat dipindai dengan cepat.
Konvensi penamaan tunggal dan jamak#
Satu gagasan bernama catatan memperoleh beberapa nama berbeda, satu untuk setiap bagian Rails. Nama kelas model ditulis tunggal dengan huruf kapital di awal setiap kata (CamelCase), misalnya Catatan. Nama tabel ditulis jamak dengan huruf kecil dan pemisah garis bawah (snake_case), yaitu catatans. Nama controller ditulis jamak dengan akhiran Controller, yaitu CatatansController, sedangkan rute menggunakan bentuk jamak yang sama seperti catatans#index. Dari satu nama model, nama-nama lainnya diturunkan secara otomatis.
Program berikut merangkum pemetaan itu dalam sebuah hash, yaitu kunci berupa nama model dan nilai berupa turunannya.
# Konvensi penamaan Rails: satu nama model memancar ke tiga tempat.
konvensi = {
"Catatan" => {
tabel: "catatans",
controller: "CatatansController",
rute: "catatans#index"
},
"KategoriCatatan" => {
tabel: "kategori_catatans",
controller: "KategoriCatatansController",
rute: "kategori_catatans#index"
}
}
konvensi.each do |model, turunan|
puts "model : #{model}"
puts "tabel : #{turunan[:tabel]}"
puts "controller: #{turunan[:controller]}"
puts "rute : #{turunan[:rute]}"
endmodel : Catatan
tabel : catatans
controller: CatatansController
rute : catatans#index
model : KategoriCatatan
tabel : kategori_catatans
controller: KategoriCatatansController
rute : kategori_catatans#indexProgram di atas hanyalah pencetakan hash, tetapi pola yang ditampilkannya adalah pola yang digunakan Rails pada setiap aplikasi. Contoh KategoriCatatan memperlihatkan perilaku kata majemuk, yaitu CamelCase dipecah menjadi kategori_catatan, kemudian hanya kata terakhir yang dijamakkan sehingga tabelnya bernama kategori_catatans. Karena penurunan ini tetap dan dapat diulang, cukup satu nama yang diketik, sedangkan nama-nama lainnya mengikuti. Pembacaan turunan[:tabel] pada perulangan juga memperlihatkan bahwa seluruh pemetaan itu hanyalah kunci symbol dan string, bukan mekanisme baru.
MVC ditemukan kembali dari keterampilan Ruby#
Rails menyusun aplikasi mengikuti pola model-view-controller (MVC), yaitu pemisahan antara data, tampilan, dan pengatur alur. Setiap bagian pola ini bertemu dengan keterampilan Ruby yang sudah diajarkan, sehingga yang benar-benar baru hanyalah nama direktori dan aturan penamaannya. Tabel berikut memetakan bagian MVC ke bentuknya di Rails beserta keterampilan Ruby yang mendasarinya.
| Bagian MVC | Bentuknya di Rails | Keterampilan Ruby yang digunakan |
|---|---|---|
| Model | kelas Catatan di app/models/catatan.rb | kelas, metode instans, mixin |
| View | template HTML dengan selipan Ruby | interpolasi string, blok pada each |
| Controller | metode aksi di CatatansController | metode instans, parameter |
| Router | config/routes.rb dan pencocokan permintaan | string, hash, percabangan |
Baris pertama berarti menulis model Rails serupa dengan menulis kelas Ruby biasa, lengkap dengan metode instans dan mixin yang menyertainya. Baris View berarti halaman HTML dibangun dari template yang memuat selipan kode Ruby, misalnya perulangan each dengan blok, sehingga bentuknya dekat dengan interpolasi string yang sudah dipraktikkan. Baris Controller dan Router berarti alur permintaan diatur oleh router, yaitu komponen yang mencocokkan permintaan dengan kode tujuannya, sebelum metode instans yang sesuai dijalankan. MVC pun tidak menuntut teori tambahan, melainkan penataan ulang atas kode yang sudah dikuasai.
Active Record sebagai kelas Ruby biasa#
Active Record adalah gem bernama activerecord yang dipasang bersama Rails, dan tugasnya adalah menjadi lapisan pemetaan objek-relasional (object-relational mapping), yaitu penghubung antara kelas Ruby dan tabel basis data. Nama gem ini terdengar seperti fitur khusus, tetapi isinya dibangun dari bagian Ruby yang sudah dikenal, yaitu kelas, pewarisan, modul, dan metode kelas. Bentuk berkas model Rails yang sungguhan seperti berikut.
# tidak-dijalankan
class Catatan < ApplicationRecord
validates :judul, presence: true
endTanda < adalah pewarisan biasa, yaitu Catatan mewarisi ApplicationRecord yang didefinisikan di app/models/application_record.rb dan berantai hingga ActiveRecord::Base. Baris validates adalah pemanggilan metode kelas, sebagaimana metode yang didefinisikan dengan def self. pada pembahasan mixin, sedangkan presence: true adalah sebuah hash dengan kunci symbol yang diberikan sebagai argumen. Tidak ada satu pun baris yang memerlukan sintaks di luar Ruby.
Model mini berikut merekonstruksi bentuk tersebut hanya dengan Ruby murni, yaitu modul Validasi disertakan melalui include dan variabel instans @kesalahan menampung hasil pemeriksaan.
# Model Rails dibangun dari bagian Ruby biasa: kelas, mixin, dan konvensi nama.
module Validasi
def valid?
@kesalahan.empty?
end
def kesalahan
@kesalahan
end
end
class Catatan
include Validasi
attr_accessor :judul
def initialize(judul)
@judul = judul
@kesalahan = []
end
def simpan
@kesalahan = []
@kesalahan << "judul tidak boleh kosong" if judul.strip.empty?
valid?
end
end
arsip = Catatan.new("Ide resep mingguan")
puts arsip.simpan
rusak = Catatan.new(" ")
puts rusak.simpan
rusak.kesalahan.each do |pesan|
puts "alasan: #{pesan}"
end
p Catatan.ancestorstrue
false
alasan: judul tidak boleh kosong
[Catatan, Validasi, Object, Kernel, BasicObject]Metode simpan pada program di atas meniru peran metode save milik Active Record, yaitu memeriksa validitas terlebih dahulu dan mengisi daftar kesalahan apabila pemeriksaan gagal. Daftar ancestors pada baris terakhir menunjukkan Validasi berada di antara Catatan dan Object, persis seperti modul-modul Active Record berada di antara kelas model dan Object pada aplikasi Rails. Perbedaannya hanya tingkat kelengkapan, bukan jenis mekanismenya, sehingga membaca kode Active Record kembali menjadi keterampilan Ruby murni.
Kesalahan umum#
Kesalahan pertama adalah menamai model dengan bentuk jamak, misalnya Catatans, karena Rails menurunkan nama tabel dari nama kelas dan penurunan itu ikut bergeser. Tabel catatans yang sudah ada tidak cocok lagi dengan nama yang dicari, dan error baru muncul ketika aplikasi berjalan, bukan ketika berkas disimpan. Perbaikannya mengikuti konvensi, yaitu nama model selalu tunggal sehingga nama tabel yang diturunkan menjadi catatans.
Kesalahan kedua adalah memisahkan nama berkas dari nama kelasnya, misalnya berkas catatan.rb berisi kelas Keterangan. Pemuat berkas Rails menuntut isi berkas mendefinisikan konstanta yang sesuai dengan nama berkasnya, sehingga ketidakcocokan semacam ini memunculkan error saat aplikasi dimuat. Menjaga pasangan nama berkas dan nama kelas tetap sejajar sejak awal mencegah kesalahan ini muncul.
Ringkasan#
- Convention over configuration memindahkan keputusan teknis yang berulang ke aturan bawaan, sehingga nama berkas menentukan perilaku dan konfigurasi hanya ditulis untuk menyimpang.
- Satu nama model memancar ke banyak tempat, yaitu kelas tunggal Catatan, tabel jamak catatans, controller CatatansController, dan rute catatans#index.
- Setiap bagian MVC bertemu dengan keterampilan Ruby dari jalur ini, yaitu kelas dan mixin untuk model, template dengan blok untuk view, serta pencocokan string dan hash untuk router.
- Active Record adalah gem yang dibangun dari kelas, pewarisan, modul, dan metode kelas Ruby, sehingga membaca kode Rails kembali menjadi keterampilan Ruby murni.
Referensi#
- Active Record Basics — Rails Guides — Dokumentasi resmi Active Record yang menjelaskan konvensi penamaan model dan tabel secara rinci.
- Panduan Ruby on Rails — Rails Guides — Pintu masuk dokumentasi resmi Rails beserta prinsip-prinsip yang mendasari strukturnya.