Action Cable y WebSockets en Rails: Guía Completa para Entrevistas Técnicas
Guia completa sobre Action Cable y WebSockets en Ruby on Rails para entrevistas tecnicas. Conexiones, canales, Solid Cable, Turbo Streams, escalabilidad con Redis y testing con ejemplos de codigo.

La comunicación en tiempo real se ha convertido en un requisito fundamental para las aplicaciones web modernas. Desde chats en vivo hasta notificaciones instantáneas y dashboards actualizados automáticamente, los usuarios esperan experiencias fluidas sin necesidad de recargar la página. Ruby on Rails resuelve esta necesidad a través de Action Cable, un framework integrado que permite trabajar con WebSockets de manera elegante y siguiendo las convenciones del ecosistema Rails. Comprender Action Cable resulta esencial para cualquier desarrollador que aspire a construir aplicaciones robustas y prepararse adecuadamente para entrevistas técnicas donde la comunicación en tiempo real sea un tema relevante.
Action Cable integra WebSockets directamente en el stack de Rails, permitiendo escribir funcionalidades en tiempo real con el mismo estilo y productividad que caracteriza al framework. En Rails 8, Solid Cable ofrece una alternativa basada en base de datos que elimina la dependencia de Redis para muchos casos de uso.
Fundamentos de WebSockets y Action Cable
WebSockets establece un canal de comunicación bidireccional y persistente entre el cliente y el servidor. A diferencia de HTTP tradicional, donde cada solicitud requiere una nueva conexión, WebSockets mantiene una conexión abierta que permite el intercambio de mensajes en ambas direcciones con latencia mínima.
Action Cable abstrae la complejidad de trabajar con WebSockets proporcionando una arquitectura basada en canales. Esta arquitectura se compone de tres elementos principales: la conexión, los canales y las suscripciones. La conexión representa el enlace WebSocket entre el cliente y el servidor, los canales encapsulan la lógica de negocio para diferentes funcionalidades, y las suscripciones permiten a los clientes recibir actualizaciones de canales específicos.
El flujo de trabajo típico comienza cuando un usuario abre la aplicación y establece una conexión WebSocket. Una vez autenticada la conexión, el cliente puede suscribirse a uno o más canales. Cuando ocurre un evento relevante en el servidor, Action Cable transmite el mensaje a todos los suscriptores del canal correspondiente.
Autenticación de Conexiones
La seguridad constituye el primer aspecto crítico al implementar WebSockets. Cada conexión debe autenticarse para garantizar que solo usuarios legítimos puedan acceder a los canales. Action Cable proporciona un mecanismo de identificación que permite asociar cada conexión con un usuario específico.
# app/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
if verified_user = User.find_by(id: cookies.encrypted[:user_id])
verified_user
else
reject_unauthorized_connection
end
end
end
endEl método identified_by declara un identificador que estará disponible en todos los canales. El método connect se ejecuta cuando se establece la conexión WebSocket y debe verificar la identidad del usuario. Si la verificación falla, reject_unauthorized_connection cierra la conexión inmediatamente.
Este patrón de autenticación mediante cookies encriptadas funciona perfectamente cuando la aplicación Rails maneja tanto la autenticación web como las conexiones WebSocket. Para arquitecturas con autenticación basada en tokens JWT, es posible pasar el token como parámetro de conexión y validarlo en el método find_verified_user.
Implementación de Canales
Los canales representan el corazón de Action Cable. Cada canal encapsula la lógica para una funcionalidad específica en tiempo real, como un chat, notificaciones o actualizaciones de dashboard. La clase base ApplicationCable::Channel proporciona métodos para gestionar suscripciones, recibir datos y transmitir mensajes.
# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
def subscribed
room = ChatRoom.find(params[:room_id])
if room.members.include?(current_user)
stream_for room
else
reject
end
end
def receive(data)
message = ChatMessage.create!(
room_id: params[:room_id],
user: current_user,
body: data["body"]
)
ChatChannel.broadcast_to(
message.room,
{ id: message.id, body: message.body, user: current_user.name }
)
end
def unsubscribed
AppearanceTracker.mark_offline(current_user)
end
endEl método subscribed se invoca cuando un cliente intenta suscribirse al canal. Aquí se realiza la autorización verificando que el usuario tenga permiso para acceder al recurso solicitado. El método stream_for establece la transmisión de mensajes asociada a un objeto específico, en este caso la sala de chat.
El método receive procesa los mensajes entrantes desde el cliente. Después de crear el mensaje en la base de datos, broadcast_to envía la información a todos los suscriptores del canal asociado con esa sala. El método unsubscribed permite ejecutar lógica de limpieza cuando el cliente se desconecta.
Integración del Cliente JavaScript
El lado del cliente requiere código JavaScript para establecer la conexión y manejar los mensajes. Rails proporciona un consumidor de Action Cable que simplifica la creación de suscripciones y el intercambio de datos.
import consumer from "./consumer"
const chatChannel = consumer.subscriptions.create(
{ channel: "ChatChannel", room_id: roomId },
{
connected() {
console.log("Connected to chat room", roomId)
},
disconnected() {
console.log("Disconnected from chat room")
},
received(data) {
const messageList = document.getElementById("messages")
messageList.insertAdjacentHTML("beforeend",
`<div class="message"><strong>${data.user}</strong>: ${data.body}</div>`
)
},
sendMessage(body) {
this.perform("receive", { body: body })
}
}
)La función subscriptions.create recibe dos argumentos: un objeto con el nombre del canal y los parámetros necesarios, y un objeto con callbacks para diferentes eventos. El callback connected se ejecuta al establecer la conexión exitosamente, disconnected cuando se pierde la conexión, y received cada vez que llega un mensaje del servidor.
El método perform permite invocar acciones definidas en el canal del servidor. En este ejemplo, sendMessage llama al método receive del ChatChannel pasando el cuerpo del mensaje como parámetro.
¿Listo para aprobar tus entrevistas de Ruby on Rails?
Practica con nuestros simuladores interactivos, flashcards y tests técnicos.
Configuración con Solid Cable en Rails 8
Rails 8 introduce Solid Cable como adaptador predeterminado para Action Cable en desarrollo y producción. Solid Cable utiliza la base de datos como backend de pub/sub, eliminando la necesidad de configurar Redis para aplicaciones de escala moderada.
# config/cable.yml (Rails 8 default)
development:
adapter: solid_cable
production:
adapter: solid_cable
connects_to:
database:
writing: cable
polling_interval: 0.1.seconds
message_retention: 1.dayLa configuración de producción especifica una base de datos dedicada para las operaciones de Action Cable. El parámetro polling_interval controla la frecuencia con que los workers verifican nuevos mensajes, mientras que message_retention determina cuánto tiempo se conservan los mensajes antes de ser eliminados automáticamente.
Para utilizar una base de datos separada, es necesario configurar la conexión múltiple en el archivo de base de datos:
# config/database.yml (Rails 8 multi-database)
production:
primary:
<<: *default
database: myapp_production
cable:
<<: *default
database: myapp_cable_production
migrations_paths: db/cable_migrateEsta separación de bases de datos permite escalar las operaciones de mensajería independientemente de la base de datos principal de la aplicación, optimizando el rendimiento bajo carga.
Patrones de Broadcasting
El broadcasting constituye el mecanismo principal para enviar mensajes desde el servidor hacia los clientes suscritos. Action Cable ofrece flexibilidad para transmitir desde diferentes contextos de la aplicación, incluyendo modelos, controladores y trabajos en segundo plano.
# Broadcasting from a model callback
class Notification < ApplicationRecord
belongs_to :user
after_create_commit :broadcast_to_user
private
def broadcast_to_user
ActionCable.server.broadcast(
"notifications_#{user_id}",
{ id: id, title: title, read: false }
)
end
end
# Broadcasting from a background job
class DashboardUpdateJob < ApplicationJob
queue_as :default
def perform(dashboard_id)
dashboard = Dashboard.find(dashboard_id)
stats = dashboard.compute_stats
ActionCable.server.broadcast(
"dashboard_#{dashboard_id}",
{ stats: stats, updated_at: Time.current.iso8601 }
)
end
endEl broadcasting desde callbacks de modelo resulta útil para notificaciones inmediatas después de crear o actualizar registros. Para operaciones que requieren cálculos intensivos, como estadísticas de dashboard, delegar el trabajo a un job en segundo plano evita bloquear la respuesta del servidor y proporciona mayor resiliencia.
La convención de nombrar canales con el formato recurso_id facilita la organización y permite a los clientes suscribirse a recursos específicos de manera predecible.
Integración con Turbo Streams
Hotwire y Turbo simplifican significativamente el trabajo con Action Cable mediante Turbo Streams. Esta integración permite actualizar fragmentos de HTML en tiempo real con mínimo código JavaScript.
# app/models/message.rb
class Message < ApplicationRecord
belongs_to :chat_room
broadcasts_to :chat_room
end
# app/views/chat_rooms/show.html.erb
<%= turbo_stream_from @chat_room %>
<div id="messages">
<%= render @chat_room.messages %>
</div>El método broadcasts_to en el modelo configura automáticamente la transmisión de cambios cuando se crean, actualizan o eliminan mensajes. En la vista, turbo_stream_from establece la suscripción al canal correspondiente. Rails genera automáticamente las actualizaciones de DOM necesarias sin escribir JavaScript adicional.
Esta aproximación declarativa reduce drásticamente la cantidad de código necesario para implementar funcionalidades en tiempo real, manteniendo la lógica de presentación en las vistas donde naturalmente pertenece.
Configuración de Redis para Alta Escala
Para aplicaciones con alto volumen de conexiones simultáneas y mensajes, Redis continúa siendo la opción recomendada como backend de pub/sub. Redis ofrece latencias extremadamente bajas y capacidad para manejar millones de operaciones por segundo.
# config/cable.yml — Redis adapter for high-scale production
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: myapp_productionEl parámetro channel_prefix resulta esencial cuando múltiples aplicaciones comparten la misma instancia de Redis, evitando colisiones de nombres de canales. La URL se obtiene de variables de entorno para mantener las credenciales fuera del código fuente.
En entornos de producción robustos, se recomienda utilizar Redis Sentinel o Redis Cluster para alta disponibilidad. Servicios administrados como Amazon ElastiCache o Redis Cloud simplifican la operación y proporcionan características adicionales de monitoreo y failover automático.
Testing de Canales
Las pruebas automatizadas garantizan que los canales funcionen correctamente y manejen apropiadamente los casos de autorización. Rails proporciona helpers específicos para probar canales de Action Cable de manera aislada.
# test/channels/chat_channel_test.rb
require "test_helper"
class ChatChannelTest < ActionCable::Channel::TestCase
test "subscribes to a valid room" do
room = chat_rooms(:general)
user = users(:alice)
stub_connection current_user: user
subscribe room_id: room.id
assert subscription.confirmed?
assert_has_stream_for room
end
test "rejects subscription for unauthorized user" do
room = chat_rooms(:private)
user = users(:outsider)
stub_connection current_user: user
subscribe room_id: room.id
assert subscription.rejected?
end
test "broadcasts messages to room subscribers" do
room = chat_rooms(:general)
stub_connection current_user: users(:alice)
subscribe room_id: room.id
assert_broadcast_on(room, hash_including(body: "Hello")) do
perform :receive, body: "Hello"
end
end
endEl método stub_connection simula una conexión autenticada con el usuario especificado. subscribe intenta suscribirse al canal con los parámetros dados, permitiendo verificar si la suscripción fue confirmada o rechazada.
La aserción assert_has_stream_for verifica que el canal esté transmitiendo correctamente para el objeto esperado. assert_broadcast_on confirma que al realizar una acción, el mensaje correspondiente se transmite a los suscriptores del canal.
Consideraciones de Rendimiento y Escalabilidad
El rendimiento de Action Cable depende de varios factores que deben considerarse durante el diseño de la aplicación. El número de conexiones simultáneas, la frecuencia de mensajes y el tamaño de los payloads impactan directamente en los recursos del servidor.
Para optimizar el rendimiento, se recomienda limitar el tamaño de los mensajes transmitidos, incluyendo solo los datos necesarios para actualizar la interfaz. Utilizar trabajos en segundo plano para operaciones costosas evita bloquear los workers de Action Cable. Implementar debouncing en el cliente previene sobrecargar el servidor con mensajes frecuentes.
El escalamiento horizontal requiere un backend de pub/sub compartido como Redis. Cuando múltiples instancias del servidor manejan conexiones WebSocket, Redis garantiza que los mensajes lleguen a todos los suscriptores independientemente del servidor al que estén conectados.
Conclusión
Action Cable proporciona una solución integrada y elegante para implementar comunicación en tiempo real en aplicaciones Rails. Desde la autenticación de conexiones hasta el testing de canales, el framework ofrece las herramientas necesarias para construir funcionalidades robustas siguiendo las convenciones del ecosistema Rails. Con la introducción de Solid Cable en Rails 8, la barrera de entrada se reduce significativamente al eliminar dependencias externas para casos de uso comunes. Dominar estos conceptos resulta fundamental para desarrolladores que buscan destacar en entrevistas técnicas y construir aplicaciones modernas que cumplan con las expectativas de los usuarios actuales.
Practicar preguntas de entrevista sobre ActionCable y WebSockets
¡Empieza a practicar!
Pon a prueba tu conocimiento con nuestros simuladores de entrevista y tests técnicos.
Etiquetas
Compartir
Artículos relacionados

ActiveRecord: Resolver problemas de consultas N+1 en Ruby on Rails
Guía completa para detectar y resolver consultas N+1 en Rails con ActiveRecord. Domina includes, preload, eager_load y herramientas de detección automática.

Preguntas de entrevista Ruby on Rails: Top 25 en 2026
Las 25 preguntas de entrevista Ruby on Rails más solicitadas. Arquitectura MVC, Active Record, migraciones, testing RSpec, APIs REST con respuestas detalladas y ejemplos de código.

Ruby on Rails 7: Hotwire y Turbo para Aplicaciones Reactivas
Guia completa de Hotwire y Turbo en Rails 7. Aprende a construir aplicaciones reactivas sin escribir JavaScript con Turbo Drive, Frames y Streams.