Setup and use ActionCable for real-time features in Rails applications using WebSockets. Use when implementing real-time updates, live notifications, broadcasting changes, or when the user mentions WebSockets, ActionCable, channels, broadcasting, or Turbo Streams over cable.
82
77%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
Optimize this skill with Tessl
npx tessl skill review --optimize ./skills/action-cable/SKILL.mdActionCable integrates WebSockets with Rails to enable real-time features. This guide covers the basic setup in this application.
app/channels/application_cable/connection.rb)The connection authenticates and authorizes the WebSocket connection using Devise/Warden.
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 = env['warden'].user
verified_user
else
reject_unauthorized_connection
end
end
end
endapp/channels/application_cable/channel.rb)Base channel class for all application channels.
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
endapp/javascript/initializers/actioncable.js)Initialize ActionCable consumer on the client side.
import * as ActionCable from '@rails/actioncable'
ActionCable.logger.enabled = falseSubscribe to a stream in views:
= turbo_stream_from record
= turbo_stream_from [record, "channel_name"]Broadcast Turbo Stream updates from controllers or background jobs:
# Append content to a target
Turbo::StreamsChannel.broadcast_append_to(
[record, "channel_name"],
target: "dom_id",
partial: "path/to/partial",
locals: { record: record }
)
# Replace content
Turbo::StreamsChannel.broadcast_replace_to(
[record, "channel_name"],
target: "dom_id",
partial: "path/to/partial",
locals: { record: record }
)
# Remove element
Turbo::StreamsChannel.broadcast_remove_to(
[record, "channel_name"],
target: "dom_id"
)View:
= turbo_stream_from current_organization, "timers"
#notificationsController:
def start_timer
# ... create timer logic ...
Turbo::StreamsChannel.broadcast_append_to(
[current_organization, "timers"],
target: "notifications",
partial: "timers/notification",
locals: { timer: @timer }
)
endconfig/cable.yml)development:
adapter: async
test:
adapter: test
production:
adapter: solid_cable
connects_to:
database:
writing: cable
polling_interval: 0.1.seconds
message_retention: 1.dayconfig/routes.rb)ActionCable is automatically mounted at /cable:
Rails.application.routes.draw do
mount ActionCable.server => '/cable'
endEnable logging in development:
// app/javascript/initializers/actioncable.js
ActionCable.logger.enabled = trueCheck connection status:
const subscription = consumer.subscriptions.create("ExampleChannel", {
connected() {
console.log("Connected to ExampleChannel")
}
})
console.log(subscription)ApplicationCable::Connectionstream_for instead of stream_from when possible for automatic scoping097ad6b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.