Belajar Ruby on Rails - Action Cable & Realtime
Episode 14 of 27

Belajar Ruby on Rails - Action Cable & Realtime

Membedah Action Cable: WebSocket sebagai fondasi realtime, channel dan streaming, autentikasi koneksi, integrasi dengan Turbo Streams, serta praktik membangun notifikasi realtime

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 13 kalian mengelola file upload, episode 14 masuk ke dunia yang paling "ajaib" dalam Rails: realtime. Dengan Action Cable, Rails bisa mendorong data ke browser secara instan tanpa browser harus menanyakan ulang — untuk chat, notifikasi, atau update status.

Mengapa episode ini penting? Karena persepsi pengguna tentang aplikasi modern adalah sesuatu yang terjadi begitu saja: komentar baru muncul tanpa reload, notifikasi muncul tanpa refresh. Action Cable membangun ini di atas WebSocket — koneksi dua arah yang persisten — dan ketika digabungkan dengan Turbo Streams dari episode 7, realtime Rails menjadi mulus tanpa satu baris JavaScript manual.

WebSocket vs HTTP Request

HTTP adalah request-response: browser meminta, server menjawab, koneksi ditutup. Untuk tahu apakah ada data baru, browser harus bertanya lagi (polling). WebSocket berbeda:

100%

WebSocket membuka koneksi sekali lalu server bisa mengirim kapan saja. Action Cable mengelola siklus hidup koneksi, autentikasi, dan broadcast.

Channel: Room Tempat Data Mengalir

Channel adalah unit logika realtime — analogi: channel adalah ruangan, dan broadcast adalah pengumuman ke semua yang ada di ruangan. Buat channel dengan generator:

Generate channel
bin/rails g channel Notifications
Rubyapp/channels/notifications_channel.rb
class NotificationsChannel < ApplicationCable::Connection
  def subscribed
    stream_from "notifications_#{current_user.id}"
  end
 
  def unsubscribed
    stop_all_streams
  end
end

stream_from "notifications_#{current_user.id}" membuat saluran unik per user. Client (browser) subscribe ke channel yang sama:

JSapp/javascript/channels/notifications_channel.js
import consumer from "./consumer"
 
consumer.subscriptions.create("NotificationsChannel", {
  received(data) {
    document.querySelector("#notifications").insertAdjacentHTML(
      "afterbegin",
      `<p>${data.body}</p>`
    )
  }
})

Autentikasi Koneksi

Koneksi WebSocket harus tahu siapa yang terhubung. Autentikasi dilakukan di connection.rb:

Rubyapp/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user
 
    def connect
      self.current_user = find_verified_user
    end
 
    private
 
    def find_verified_user
      user_id = session[:user_id] || cookies.signed[:user_id]
      User.find_by(id: user_id) || reject_unauthorized_connection
    end
  end
end

identified_by :current_user membuat current_user tersedia di channel; reject_unauthorized_connection memutus koneksi tanpa auth. Ini garis pertahanan pertama realtime — jangan pernah broadcast ke stream publik tanpa filter identitas.

Broadcast: Mengirim Data dari Server

Server mengirim data kapan pun — dari controller, job, atau model:

RubyBroadcast dari controller
def create
  @comment = @post.comments.new(comment_params)
  if @comment.save
    NotificationsChannel.broadcast_to(current_user, { body: "Post #{@post.title} mendapat komentar baru" })
    redirect_to @post
  else
    render :new, status: :unprocessable_entity
  end
end

broadcast_to(recipient, payload) mengirim ke stream user tertentu. Untuk yang lebih umum, ActionCable.server.broadcast("stream_name", payload) broadcast ke semua subscriber stream tersebut.

Integrasi dengan Turbo Streams

Kombinasi Action Cable + Turbo Streams adalah killer feature realtime Rails: server mengirim HTML Turbo Stream, dan Turbo menerapkannya ke halaman secara otomatis — tanpa JavaScript custom:

RubyBroadcast Turbo Stream
def create
  @comment = @post.comments.new(comment_params)
  if @comment.save
    @comment.broadcast_append_to @post
    redirect_to @post
  else
    render :new, status: :unprocessable_entity
  end
end

broadcast_append_to @post (disediakan broadcasts di model) mengirim Turbo Stream append yang otomatis menambahkan _comment.html.erb ke halaman semua user yang sedang melihat post tersebut — tanpa mereka harus me-refresh. Realtime di Rails 8 jadi semudah satu baris.

Tip

Untuk chat sederhana, framework mental yang perlu diingat: browser subscribe ke channel, server broadcast ke stream, Turbo menerapkan HTML. Tidak perlu JavaScript framework — koneksi dikelola Action Cable, UI dikelola Turbo Streams.

Konfigurasi Production

Di production, WebSocket berjalan sebagai bagian dari server (atau adapter terpisah). Rails 8 dengan Solid Cable bisa memakai database sebagai pub/sub backend tanpa Redis:

Rubyconfig/environments/production.rb
config.action_cable.url = "/cable"
config.action_cable.mount_path = "/cable"
# Solid Cable default: database-driven pub/sub

config.action_cable.url = "/cable" memastikan browser mengarah ke mount path yang benar saat app di belakang proxy. Solid Cable menghapus ketergantungan Redis untuk kebanyakan aplikasi — kita bedah lebih dalam di episode 22.

Common Pitfalls

  • Broadcast ke stream tanpa identitas — semua user menerima data pribadi; selalu sertakan current_user.id di nama stream atau pakai broadcast_to.
  • Koneksi tanpa autentikasifind_verified_user harus diverifikasi; reject_unauthorized_connection adalah default yang aman.
  • Channel tidak di-subscribe client — broadcast terkirim tapi tidak tampil; pastikan consumer.subscriptions.create cocok dengan nama channel.
  • WebSocket di blokir proxy — konfigurasi Nginx/Caddy perlu upgrade Upgrade: websocket headers; tanpa itu koneksi hang.
  • Broadcast berlebihan — tiap event mengirim data; throttle update status yang sering berubah.

Penutup

Episode 14 membekali kalian Action Cable: WebSocket sebagai koneksi persisten, channel sebagai ruangan data dengan stream_from/broadcast_to, autentikasi di connection.rb, dan integrasi dengan Turbo Streams yang membuat realtime Rails semudah broadcast_append_to.

Inti yang harus dibawa pulang:

  • WebSocket = koneksi dua arah persisten; Action Cable mengelolanya.
  • Channel: subscribedstream_from, server kirim via broadcast.
  • Autentikasi koneksi di ApplicationCable::Connection via identified_by.
  • Turbo Streams + broadcast = update halaman realtime tanpa JS manual.
  • Solid Cable (Rails 8) memakai database sebagai pub/sub backend.

Di episode 15 selanjutnya kita akan membedah API Only & Rails APIrails new --api, serialization (jbuilder), versioning API, dan token auth untuk SPA & mobile. Sampai jumpa di episode 15!

Belajar Ruby on Rails - Action Cable & Realtime | Belajar Ruby on Rails