Action Cable
📡 Action Cable
express2-6 covered Socket.IO for exactly this in Express; Action Cable is Rails' own built-in answer to the same problem.
🔗 Connections and Channels
A Connection is established once per browser tab, the moment the WebSocket handshake happens — it's where authentication lives, reusing the same encrypted session cookie rails2-1 already set during a normal HTTP login. identified_by :current_user declares that every message flowing through this connection knows which user it belongs to, and reject_unauthorized_connection refuses the handshake entirely for anyone who fails the check — the WebSocket equivalent of rails2-1's require_login before_action.
A single Connection can host many Channels — one per feature that needs real-time updates:
stream_for post subscribes this client to a stream scoped to one specific post — Action Cable derives a unique stream identifier from the object automatically, so every browser tab currently viewing that post's comments joins the same stream, and tabs viewing a different post don't.
📢 Broadcasting
after_create_commit is a callback (from Course 1's validations/callbacks chapter, rails1-7) that fires only after the database transaction actually commits — broadcasting before that point risks telling clients about a comment that a later rollback then undoes. broadcast_to(post, ...) pushes the payload to every client streaming that specific post, reusing the exact same CommentSerializer Chapter 5 wrote for the JSON API — one source of truth for "what a comment looks like," whether it arrives via a REST request or a live broadcast.
💻 The Client Side
The client subscribes with the same post_id param the server's subscribed method reads, and received fires every time a broadcast arrives on that stream — no polling, no manually re-fetching the comments list.
📜 Action Cable vs Socket.IO
Rails Action Cable vs Express + Socket.IO (express2-6)
| Concern | Express + Socket.IO | Rails Action Cable |
|---|---|---|
| Connection auth | io.use() middleware | Connection#connect, identified_by |
| Grouping clients | Rooms (socket.join(room)) | Streams (stream_for / stream_from) |
| Sending a message | io.to(room).emit(event, data) | Channel.broadcast_to(object, data) |
| Feature organization | Event names on one connection | Separate channel class per feature |
| Triggering a broadcast | Called explicitly wherever needed | Often a model callback (after_create_commit) |
The concepts map closely — a Socket.IO "room" and an Action Cable "stream" solve the same "only these clients get this message" problem. The organizational difference is Rails' usual one: a dedicated channel class per feature (CommentsChannel, NotificationsChannel) instead of a flat set of event name strings on one shared connection.
💻 Coding Challenges
Challenge 1: A Notifications Channel
Write a NotificationsChannel where subscribed streams for the current connection's current_user (not a param — the user identified on the connection itself).
Goal: Practice streaming scoped to the authenticated user rather than a URL parameter.
Challenge 2: Broadcasting on Create
Add an after_create_commit callback to a Notification model that broadcasts the new notification (serialized) to the NotificationsChannel stream for its owning user.
Goal: Practice triggering a broadcast from a model callback, tied to the right stream.
Challenge 3: Client Subscription
Write the JavaScript client code subscribing to NotificationsChannel and appending each received notification to a #notifications element on the page.
Goal: Practice wiring the client side of a channel subscription to a broadcast.
Action Cable is the right tool when data genuinely needs to appear without the user doing anything — a live chat, a notification badge. If a page only needs "show me the latest data when I next visit or refresh," a plain request (Chapter 5's JSON API, or a normal page load) is simpler, has one less moving part (no persistent connection to manage), and is usually the better default.
🎯 What's Next
Next chapter: Hotwire — Turbo & Stimulus — how modern Rails apps add interactivity to server-rendered HTML without reaching for a full frontend framework.