# 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. - Published: 2026-05-07 - Updated: 2026-05-07 - Author: Anthony Fillion-Maillet - Tags: ruby on rails, action cable, websockets, tiempo real, solid cable, rails 8 - Reading time: 11 min --- 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. ```ruby # 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 end ``` El 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. ```ruby # 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 end ``` El 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. ```javascript // app/javascript/channels/chat_channel.js 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", `
` ) }, 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. ## 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. ```yaml # 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.day ``` La 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: ```ruby # config/database.yml (Rails 8 multi-database) production: primary: <<: *default database: myapp_production cable: <<: *default database: myapp_cable_production migrations_paths: db/cable_migrate ``` Esta 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. ```ruby # 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 end ``` El 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. ```ruby # 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 %>