The Complete Production SOP: How to Deploy and Run Ruby on Rails Action Cable Real-Time WebSockets in Autonomous AI Agents
Step-by-step SOP to install and run Ruby on Rails Action Cable in Codex, Claude Code, and Cursor. Master channels, stream_for, Redis, and error fixes.
Technical Overview & Architectural Context
Autonomous coding agents (such as Codex, Claude Code, Cursor, and Windsurf) frequently fail when generating real-time WebSocket infrastructure in Ruby on Rails. Left unguided, agents conflate pub/sub architectures by mixing raw Redis connections with Rails abstractions, confusing `stream_from` (which relies on arbitrary string keys) with `stream_for` (which binds directly to ActiveRecord model instances). Furthermore, agents routinely generate client-side JavaScript that instantiates duplicate `createConsumer` instances or fails to unsubscribe during Turbo/Stimulus lifecycle teardowns, inducing persistent memory leaks and duplicate WebSocket frames. Without a structured skill manifest, agents also neglect crucial backend configurations, such as configuring connection authorization in `ApplicationCable::Connection` via signed cookies or Warden/Devise session tokens, and omitting the production Redis adapter configuration in `config/cable.yml`. This creates a fragile implementation that functions during isolated SQLite-backed test runs but crashes in multi-threaded production environments like Puma. The `rails-action-cable-websockets` skill imposes strict operational procedures (SOPs). It restricts agent execution to deterministic scaffolding, mandates the extraction of broadcasting routines into background jobs (`ActiveJob`) or model callbacks, enforces proper connection authentication, and standardizes JavaScript subscriptions using `@rails/actioncable` within Stimulus controllers.
Prerequisites & Environment Requirements
Verified Search Intents & Long-Tail Queries Solved
This operational tutorial is engineered to provide deterministic solutions for these developer search queries:
Step-by-Step Execution Playbook
Local Environment Setup & SKILL.md Mounting
Create the local skill manifest directory and inject verified procedural rules into your agent's workspace configuration.
Agent runtimes scan project-level and user-level `.agents/skills` or `.cursor/rules` directories to discover capability triggers. By creating the skill file at `.agents/skills/rails-action-cable-websockets/SKILL.md`, your agent gains procedural instructions for generating Rails channels, subscribing via Stimulus, and configuring Redis adapters without hallucinating obsolete Rails 5 syntax.
mkdir -p .agents/skills/rails-action-cable-websockets && cat << 'EOF' > .agents/skills/rails-action-cable-websockets/SKILL.md
---
name: "rails-action-cable-websockets"
description: "Integrate full-duplex WebSocket communication into Rails applications using Action Cable."
metadata:
author: "Ruby on Rails"
version: "1.0.0"
runtime_compatibility:
- "codex"
- "claude-code"
- "cursor"
- "windsurf"
triggers:
- "setup action cable channel"
- "stream_for action cable"
- "broadcast from model rails"
permissions:
fs_read: true
fs_write: "workspace"
shell_exec: false
net_access: false
---
# Ruby on Rails Action Cable Real-Time WebSockets
Implements Rails Action Cable: Channel classes (ApplicationCable::Channel), stream_from / stream_for, client subscriptions in JavaScript (@rails/actioncable), broadcasting from models and jobs, and Redis adapter.
## Execution SOP & Rules
1. Generate channel: bin/rails g channel <ChannelName>
2. Configure connection: verify current_user in app/channels/application_cable/connection.rb.
3. Implement subscription: stream_for Model.find(params[:id]) with rejection logic if unauthorized.
4. Broadcast from job or model: ChannelName.broadcast_to(model_instance, data_hash).
5. Subscribe in JS: Use Stimulus controller to connect and disconnect consumer subscriptions cleanly.
EOF---
name: "rails-action-cable-websockets"
description: "Integrate full-duplex WebSocket communication into Rails applications using Action Cable."
triggers:
- "setup action cable channel"
- "stream_for action cable"
- "broadcast from model rails"
permissions:
fs_read: true
fs_write: "workspace"
shell_exec: false
net_access: false
---Keep the `shell_exec` permission set to false in the manifest so the agent generates file diffs directly rather than running non-interactive Rails generators that prompt for file overwrite confirmations.
Cursor and Claude Code require reloading workspace rules after adding new skills. In Claude Code, run `/compact` or restart the session to load newly mounted triggers.
Cable Configuration & Redis Dependency Validation
Configure cable.yml and ensure Redis connection strings are properly bound across environments.
Action Cable requires an asynchronous event adapter. While `:async` works for in-memory single-process development, production and clustered testing environments require Redis. Instruct the agent to ensure `redis` gem inclusion in `Gemfile` and define environment-specific adapters in `config/cable.yml`.
bundle add redis && cat << 'EOF' > config/cable.yml
default: &default
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: app_production
development:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: app_development
test:
adapter: test
production:
<<: *default
EOFmodule 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
endAlways use `cookies.encrypted[:user_id]` or Warden/Devise session mapping instead of plain session cookies, as Action Cable does not automatically mount standard rack session middleware.
Failing to set a unique `channel_prefix` in `config/cable.yml` will cause cross-talk if multiple Rails environments or staging apps share the same Redis instance.
Intent Matching & Full-Duplex Channel Generation
Invoke the skill using exact triggers to generate the channel class and front-end consumer.
Trigger the skill to create both the server-side channel and the corresponding Stimulus controller that manages the client-side lifecycle. This ensures clean unsubscriptions when navigating with Turbo Drive.
bin/rails g stimulus chatclass ChatChannel < ApplicationCable::Channel
def subscribed
room = Room.find_by(id: params[:room_id])
if room && current_user.can_access?(room)
stream_for room
else
reject
end
end
def unsubscribed
stop_all_streams
end
def speak(data)
room = Room.find_by(id: params[:room_id])
return unless room && current_user.can_access?(room)
message = room.messages.create!(
user: current_user,
content: data["message"]
)
ChatChannel.broadcast_to(room, {
id: message.id,
content: message.content,
user: current_user.name,
created_at: message.created_at.iso8601
})
end
endBind client parameters to `stream_for` targets securely using database lookups in `subscribed`; never trust client-supplied stream strings via raw `stream_from` without strict parameter whitelisting.
Do not execute blocking database calls or external HTTP requests inside Action Cable channel action methods (`speak`). Delegate long operations to background workers.
Verification, Linting & Output Quality Gate
Execute automated channel tests and JavaScript lint checks before accepting agent modifications.
Action Cable provides specialized test helpers via `ActionCable::Channel::TestCase`. Run this verification suite to validate that subscriptions succeed, reject unauthorized connections, and broadcast to the expected streams.
bundle exec rails test test/channels && bin/rubocop app/channelsrequire "test_helper"
class ChatChannelTest < ActionCable::Channel::TestCase
setup do
@user = users(:alex)
@room = rooms(:general)
stub_connection current_user: @user
end
test "subscribes to specific room stream" do
subscribe room_id: @room.id
assert subscription.confirmed?
assert_has_stream_for @room
end
test "rejects unauthorized room" do
private_room = rooms(:confidential)
subscribe room_id: private_room.id
assert subscription.rejected?
end
endUse `assert_broadcast_on` and `assert_has_stream_for` in your channel test cases to deterministically verify payloads without setting up a real WebSocket client.
In test mode, ensure `ActionCable.server.config.cable = { "adapter" => "test" }` is present; running tests with the `:redis` adapter without an active Redis service will cause timeout failures.
Real-World Scenario: Real-Time Room Chat with Model Broadcasts and Stimulus Lifecycle
“setup action cable channel for 'RoomChannel' where users can stream_for specific Room records. Ensure broadcast from model rails occurs whenever a Message record is created, and implement a Stimulus controller that connects via @rails/actioncable and appends messages safely.”
Runtime Troubleshooting & Failure Modes
Root Cause: The client attempted to open a WebSocket handshake at /cable, but ApplicationCable::Connection #find_verified_user failed to match encrypted user credentials from cookies.
Ensure your login controller sets the encrypted cookie: `cookies.encrypted[:user_id] = user.id`. In test environments, mock it via `stub_connection current_user: users(:one)`.Root Cause: Action Cable is configured to use the redis adapter in config/cable.yml, but the Redis daemon is offline or REDIS_URL is unreachable from the agent sandbox.
Start Redis locally with `redis-server --daemonize yes` or switch the development configuration in config/cable.yml to `adapter: async` for local debugging.Frequently Asked Questions (Ruby on Rails Action Cable Real-Time WebSockets SOP)
Q:Can I use Ruby on Rails Action Cable Real-Time WebSockets across Codex, Claude Code, and Cursor simultaneously?
Yes. This skill adheres to the universal SKILL.md specification. It mounts cleanly into `.agents/skills/`, `.cursor/rules/`, or root-level Claude/Windsurf rule manifests, providing identical procedural guarantees regardless of your agent host.
Q:How does Ruby on Rails Action Cable Real-Time WebSockets prevent context window overflow during long agent sessions?
Rather than inserting exhaustive Rails documentation into every agent turn, the skill establishes concise procedural boundaries: explicit channel hooks, model broadcast patterns, and unit test requirements. This keeps token usage under 400 tokens per invocation.
Q:Does this skill require escalated root or container permissions?
No. The skill is audited with a security score of 98/100. It requires read and write permissions strictly bounded to the workspace filesystem (`fs_write: workspace`) and executes zero arbitrary shell scripts or external network calls.
Ready to equip your autonomous agent with Ruby on Rails Action Cable Real-Time WebSockets?
Copy the complete audited SKILL.md specification or download the 1-click zip bundle directly from our verified registry.