Sebelum kita mulai instal-instal dan ngetik kode, mari kita resapi dulu wejangan dari dua dimensi yang beda, biar batin dan logika kita sinkron.
Pertama, dari kitab kuning legendaris Ta'lim Muta'allim karya Syekh Az-Zarnuji. Di situ tertulis kaidah emas:
"Tsumma laa budda minal jiddi wal muwaadzobati"
Artinya kurang lebih, dalam menuntut ilmu itu hukumnya fardhu (wajib) buat bersungguh-sungguh dan tekun berkelanjutan (konsisten). Belajar Ruby digabung Oracle ini tantangannya lumayan, Cing. Kalo kagak tekun, bisa gampang putus asa di tengah jalan pas nemu error.
Kedua, dari buku babonnya anak Ruby, Practical Object-Oriented Design in Ruby karya Mpok Sandi Metz:
"Design is more the art of preserving changeability than it is the act of achieving perfection."
Maksudnya, nulis kode program itu seninya ada di gimana caranya kodingan kita gampang diubah-ubah di masa depan, bukan sekadar ngejar kesempurnaan di awal doang.
Tutorial Lengkap Membuat Web E-Commerce dengan Ruby dan Oracle Database
Kalo biasa ngulik XML sama HTML di Blogger demi dapet skor mobile cepek di PageSpeed, ketelitian ngerancang struktur kayak gitu bakal kepake banget di mari. Backend pake Oracle ini ibarat fondasi daleman yang kuat, biar frontend-nya bisa sedap dipandang—sama kayak pas ngerancang thumbnail video gaming, visualnya harus narik, tapi metadata di belakangnya juga kudu rapi biar dapet engagement maksimal.
Yuk, tarik napas panjang, kita mulai babad alas!
Buka Gerbang "Sultan" (Setup Ruby & Oracle)
Kenapa ane sebut gerbang Sultan? Karena Oracle ini bukan database ecek-ecek. Ini database kelas kakap (Enterpise) yang biasa dipake bank sama perusahaan gede. Nah, Ruby itu bahasa pemrograman yang elegan dan sat-set. Nggabungin keduanya butuh jembatan khusus.
Di penjelasan ini, target kita belum bikin aplikasi jualan, tapi masang fondasi dan mastiin Ruby bisa "ngobrol" nyambung sama Oracle.
Pastiin di laptop atau PC ente udah terpasang tiga barang ini:
- Ruby: Kalo pake Windows, sedot RubyInstaller (pilih yang ada Devkit-nya). Kalo Mac/Linux bisa pake RVM atau rbenv.
- Oracle Database: Kalo buat belajar, download aja Oracle Database Express Edition (XE).
- Oracle Instant Client: Ini jembatannya. Kudu di-download dari situs Oracle dan diatur Environment Variables (PATH)-nya.
Di dunia Ruby, ekstensi itu disebutnya Gem. Buka Terminal atau CMD (Run as Administrator), trus ketik mantra ini:
gem install ruby-oci8
Catatan: Kalo error, biasanya karena Oracle Instant Client belom kebaca sama sistem. Kudu sabar dan teliti ngatur PATH-nya. Inget petuah Syekh Az-Zarnuji di atas, kudu muwaadzobah (tekun)!
Bikin folder baru
toko_ruby. Di dalemnya, bikin file tes_koneksi.rb dan masukin kodingan ini:
# Panggil jembatannya dulu
require 'oci8'
puts "Mencoba ngetok pintu Oracle..."
begin
# Format: OCI8.new('username', 'password', 'alamat_server/Service_Name')
koneksi = OCI8.new('sistem_toko', 'rahasia123', 'localhost:1521/XEPDB1')
puts "Alhamdulillah, koneksi ke Oracle tembus, Cing!"
# Coba nanya jam server ke Oracle buat bukti
koneksi.exec('SELECT SYSDATE FROM DUAL') do |baris|
puts "Waktu di server database sekarang: #{baris[0]}"
end
# Tutup pintu biar memori kagak bocor
koneksi.logoff
rescue OCIError => e
puts "Waduh, gagal nyambung nih. Cek lagi dah: #{e.message}"
end
Arahin terminal ke folder
toko_ruby, trus jalanin mantranya:
ruby tes_koneksi.rb
Alhamdulillah, koneksi ke Oracle tembus, Cing!
Waktu di server database sekarang: 2026-04-30 10:45:00
Ngecor Fondasi (Bikin Tabel di Oracle pake Ruby)
Di penjelasan pertama kita udah nembus gerbang Oracle. Waktunya kita ngecor fondasi alias bikin Tabel Database buat nyimpen barang jualan e-commerce kita.
"Maa istawda'a fil ghaibi minas saraair, dzahara fisy syahaadati minadz dzawahir."
(Apa yang tersimpan di dalam batin/rahasia, akan tampak bekasnya pada lahiriah/kenyataan). - Syekh Ibnu Atha'illah as-Sakandari
Kalo "batin"-nya (tabel Oracle) rapi, tampilan luarnya bakal mulus. Ini persis kayak kaidah ngatur struktur kode XML di Blogger demi skor PageSpeed 100.
Bikin file
bikin_tabel.rb, ketik kodingan di bawah ini:
require 'oci8'
begin
koneksi = OCI8.new('sistem_toko', 'rahasia123', 'localhost:1521/XEPDB1')
puts "Koneksi aman, Cing! Mulai ngaduk semen buat tabel..."
# Blueprint rak etalasenya pake bahasa SQL Oracle.
rancangan_sql = <<-SQL
CREATE TABLE barang_dagangan (
id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
nama_barang VARCHAR2(100) NOT NULL,
deskripsi VARCHAR2(500),
harga NUMBER NOT NULL,
stok NUMBER DEFAULT 0
)
SQL
koneksi.exec(rancangan_sql)
puts "Alhamdulillah, rak etalase (tabel) 'barang_dagangan' udah berdiri kokoh!"
rescue OCIError => e
puts "Waduh, ada yang salah pas ngecor nih: #{e.message}"
ensure
if koneksi
koneksi.logoff
puts "Pintu Oracle udah ditutup rapi."
end
end
Misi Tambahan: Masukin Barang ke Etalase (Insert Data)
Bikin file baru tambah_barang.rb buat ngisi datanya (DML):
require 'oci8'
begin
koneksi = OCI8.new('sistem_toko', 'rahasia123', 'localhost:1521/XEPDB1')
puts "Koneksi tembus! Siap bongkar muatan barang..."
# Bind Variables (:nama, :deskripsi) biar aman dari SQL Injection
sql_tambah = <<-SQL
INSERT INTO barang_dagangan (nama_barang, deskripsi, harga, stok)
VALUES (:nama, :deskripsi, :harga, :stok)
SQL
kursor = koneksi.parse(sql_tambah)
# Barang 1 & 2
kursor.exec('Kaos Polos Mbois', 'Kaos bahan katun adem, cocok buat nongkrong', 55000, 24)
kursor.exec('Kopi Bubuk Asli', 'Kopi item racikan warkop, bikin melek nulis kode', 25000, 50)
# Wajib Commit di Oracle!
koneksi.commit
puts "Dua barang andalan udah sukses masuk etalase!"
rescue OCIError => e
puts "Gagal bongkar muatan, Cing: #{e.message}"
ensure
koneksi.logoff if koneksi
end
Buka Toko & Majang Barang (Read Data)
Barang udah di dalem Oracle, sekarang kita tarik datanya biar bisa dibaca (Proses Read).
require 'oci8'
def format_rupiah(angka)
angka.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1.').reverse
end
begin
koneksi = OCI8.new('sistem_toko', 'rahasia123', 'localhost:1521/XEPDB1')
puts "\n============================================="
puts " SELAMAT DATANG DI TOKO RUBY SULTAN "
puts "=============================================\n\n"
sql_tarik_data = "SELECT id, nama_barang, deskripsi, harga, stok FROM barang_dagangan ORDER BY id ASC"
koneksi.exec(sql_tarik_data) do |baris|
id_barang = baris[0]
nama = baris[1]
deskripsi = baris[2]
harga = format_rupiah(baris[3])
stok = baris[4]
puts "[#{id_barang}] #{nama.upcase}"
puts " Keterangan : #{deskripsi}"
puts " Harga : Rp #{harga}"
puts " Sisa Stok : #{stok} Pcs"
puts "---------------------------------------------"
end
rescue OCIError => e
puts "Waduh, etalase macet nutup nih: #{e.message}"
ensure
koneksi.logoff if koneksi
end
Bengkel Revisi (Update) dan Sapu Jagat (Delete)
Kita bakal namatin siklus maut CRUD di terminal dengan nambahin fitur Update (Revisi) dan Delete (Hapus). Data yang udah usang itu "mudarat", bikin database bengkak.
require 'oci8'
begin
koneksi = OCI8.new('sistem_toko', 'rahasia123', 'localhost:1521/XEPDB1')
# UPDATE wajib pake WHERE!
sql_revisi = <<-SQL
UPDATE barang_dagangan
SET harga = :harga_baru, stok = :stok_baru
WHERE id = :id_barang
SQL
koneksi.exec(sql_revisi, 60000, 20, 1) # Update ID 1
koneksi.commit
puts "Harga sama stok sukses di-update!"
ensure
koneksi.logoff if koneksi
end
require 'oci8'
begin
koneksi = OCI8.new('sistem_toko', 'rahasia123', 'localhost:1521/XEPDB1')
# DELETE wajib pake WHERE juga!
sql_hapus = "DELETE FROM barang_dagangan WHERE id = :id_barang"
koneksi.exec(sql_hapus, 2) # Hapus ID 2 (Kopi)
koneksi.commit
puts "Beres, Cing! Barang udah musnah."
ensure
koneksi.logoff if koneksi
end
Ngebuka Pintu Web (Bikin Server pake Sinatra)
Sejauh ini kita mainan di terminal. Sekarang kita sulap jadi Website beneran pake Sinatra, framework Ruby yang super ringan.
gem install sinatra
Bikin folder views dan masukin file HTML/ERB ini di dalemnya:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Toko Sultan Oracle - Belanja Ngacir</title>
<style>
body { font-family: sans-serif; background-color: #f4f4f9; padding: 20px; }
.grid-container { display: flex; gap: 20px; flex-wrap: wrap; justify-content: center; }
.card { background: white; border-radius: 10px; padding: 20px; width: 280px; box-shadow: 0 4px 6px rgba(0,0,0,0.05); }
.harga { color: #e74c3c; font-weight: bold; font-size: 1.2em; }
.btn-beli { display: block; text-align: center; background-color: #27ae60; color: white; padding: 10px; text-decoration: none; border-radius: 5px; }
</style>
</head>
<body>
<h1 style="text-align: center;">Katalog Toko Sultan</h1>
<div class="grid-container">
<% @daftar_barang.each do |barang| %>
<div class="card">
<h3><%= barang[:nama] %></h3>
<p><%= barang[:deskripsi] %></p>
<p class="harga">Rp <%= barang[:harga] %></p>
<p class="stok">Sisa Stok: <%= barang[:stok] %></p>
<a href="#" class="btn-beli">🛒 Beli Sekarang</a>
</div>
<% end %>
</div>
</body>
</html>
Dan ini pelayan web-nya (Server Sinatra):
require 'sinatra'
require 'oci8'
get '/' do
@daftar_barang = []
begin
koneksi = OCI8.new('sistem_toko', 'rahasia123', 'localhost:1521/XEPDB1')
koneksi.exec("SELECT id, nama_barang, deskripsi, harga, stok FROM barang_dagangan ORDER BY id ASC") do |baris|
harga_rupiah = baris[3].to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1.').reverse
@daftar_barang << {
id: baris[0], nama: baris[1], deskripsi: baris[2],
harga: harga_rupiah, stok: baris[4]
}
end
ensure
koneksi.logoff if koneksi
end
erb :etalase
end
Jalanin ruby toko_web.rb di terminal, trus buka http://localhost:4567 di browser lu!
Nyambungin Jalur Cuan (WhatsApp Checkout)
Biar tombol "Beli Sekarang" kaga pajangan doang, kita arahin ke WhatsApp pake URL Encoding Ruby.
<%
require 'uri'
nomor_wa = "6281234567890"
teks_pesan = "Halo Admin, ane kepincut sama barang ini:\n" +
"📦 Nama Barang: #{barang[:nama]}\n" +
"💰 Harga: Rp #{barang[:harga]}\n"
teks_aman = URI.encode_www_form_component(teks_pesan)
link_checkout = "https://wa.me/#{nomor_wa}?text=#{teks_aman}"
%>
<a href="<%= link_checkout %>" target="_blank" class="btn-beli">🛒 Beli via WhatsApp</a>
Bikin Pintu Belakang (Formulir Tambah Barang via Web)
Biar nambah barang gampang, kita bikin rute GET /tambah (nampilin form) dan POST /simpan (nyimpen ke DB).
get '/tambah' do
erb :tambah_barang
end
post '/simpan' do
nama = params[:nama_barang]
deskripsi = params[:deskripsi]
harga = params[:harga]
stok = params[:stok]
begin
koneksi = OCI8.new('sistem_toko', 'rahasia123', 'localhost:1521/XEPDB1')
sql_simpan = "INSERT INTO barang_dagangan (nama_barang, deskripsi, harga, stok) VALUES (:1, :2, :3, :4)"
koneksi.exec(sql_simpan, nama, deskripsi, harga, stok)
koneksi.commit
ensure
koneksi.logoff if koneksi
end
redirect '/'
end
<form action="/simpan" method="POST">
<label>Nama Barang:</label>
<input type="text" name="nama_barang" required>
<label>Harga:</label>
<input type="number" name="harga" required>
<button type="submit">💾 Simpan ke Database</button>
</form>
Masang Satpam di Pintu Belakang (Authentication)
Jangan sampe sembarang orang ngetik /tambah trus ngacak-ngacak DB lu. Kita pasang Basic Auth.
helpers do
def satpam_jaga!
return if authorized?
headers['WWW-Authenticate'] = 'Basic realm="Gudang Rahasia"'
halt 401, "Akses Ditolak, Cing!\n"
end
def authorized?
@auth ||= Rack::Auth::Basic::Request.new(request.env)
@auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == ['admin', 'rahasia123']
end
end
get '/tambah' do
satpam_jaga! # Panggil satpam di mari!
erb :tambah_barang
end
Bikin Kolom Pencarian (Search Feature)
Biar pembeli kagak pegel nge-scroll ratusan barang, kita pasang Search pake SQL LIKE.
get '/' do
@daftar_barang = []
kata_kunci = params[:cari]
begin
koneksi = OCI8.new('sistem_toko', 'rahasia123', 'localhost:1521/XEPDB1')
if kata_kunci && !kata_kunci.strip.empty?
sql_tarik = "SELECT id, nama_barang, deskripsi, harga, stok FROM barang_dagangan
WHERE LOWER(nama_barang) LIKE :1 ORDER BY id ASC"
pencarian_aman = "%#{kata_kunci.downcase}%"
kursor = koneksi.exec(sql_tarik, pencarian_aman)
else
sql_tarik = "SELECT id, nama_barang, deskripsi, harga, stok FROM barang_dagangan ORDER BY id ASC"
kursor = koneksi.exec(sql_tarik)
end
# Looping data kursor kayak biasa...
end
end
🧐 FAQ: Duet Maut Ruby & Oracle "Sultan"
Q1: Bang, Ruby pake Sinatra kalo dibandingin sama template Blogger, menang mana skor PageSpeed-nya?
Ruby dan Oracle itu mesin backend yang ngacir badai. Tapi skor PageSpeed tetep dari tampilan depannya (frontend). Kalo HTML/CSS di file .erb berantakan atau render-blocking, ya skor tetep anjlok. Bawa mental optimasi Blogger lu ke Sinatra!
Q2: Kenapa muncul error ORA-12154: TNS:could not resolve...?
Penyakit langganan Oracle nih! Jembatan Instant Client kagak nemu alamat rumah Oracle-nya. Cek file tnsnames.ora, pastiin Service Name sama alamat di Ruby (localhost:1521/XEPDB1) udah sama persis.
Q3: Pas deploy ke VPS, kenapa website-nya kagak bisa dibuka?
Sinatra jalan di port 4567, browser nyarinya di port 80. Solusinya: Ente kudu ngatur Reverse Proxy pake Nginx. Nginx nangkep tamu dari port 80, trus digiring ke kamar Sinatra (4567). Jangan lupa buka Firewall VPS ente!
ruby-oci8, siklus CRUD utuh, ngeracik tampilan pake Sinatra, sampe ngebahas VPS. Sekarang lu udah punya senjata rahasia kelas berat: Kombinasi Elegan Ruby dan Kekuatan Enterprise Oracle. Gasss!