action-cable

📁 rolemodel/rolemodel-skills 📅 9 days ago
9
总安装量
9
周安装量
#32622
全站排名
安装命令
npx skills add https://github.com/rolemodel/rolemodel-skills --skill action-cable

Agent 安装分布

github-copilot 9
opencode 8
gemini-cli 8
codex 8
kimi-cli 8
amp 8

Skill 文档

ActionCable Setup

Overview

ActionCable integrates WebSockets with Rails to enable real-time features. This guide covers the basic setup in this application.

Core Components

1. Connection (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
end

2. Channel (app/channels/application_cable/channel.rb)

Base channel class for all application channels.

module ApplicationCable
  class Channel < ActionCable::Channel::Base
  end
end

3. JavaScript Setup (app/javascript/initializers/actioncable.js)

Initialize ActionCable consumer on the client side.

import * as ActionCable from '@rails/actioncable'

ActionCable.logger.enabled = false

Broadcasting Updates

With Turbo Streams (recommended)

Subscribe 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"
)

Example: Organization-scoped notifications

View:

= turbo_stream_from current_organization, "timers"

#notifications

Controller:

def start_timer
  # ... create timer logic ...

  Turbo::StreamsChannel.broadcast_append_to(
    [current_organization, "timers"],
    target: "notifications",
    partial: "timers/notification",
    locals: { timer: @timer }
  )
end

Configuration

Cable URL (config/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.day

Routes (config/routes.rb)

ActionCable is automatically mounted at /cable:

Rails.application.routes.draw do
  mount ActionCable.server => '/cable'
end

Debugging

Enable logging in development:

// app/javascript/initializers/actioncable.js
ActionCable.logger.enabled = true

Check connection status:

const subscription = consumer.subscriptions.create("ExampleChannel", {
  connected() {
    console.log("Connected to ExampleChannel")
  }
})

console.log(subscription)

Security Considerations

  • Always authenticate connections in ApplicationCable::Connection
  • Validate params in channel subscriptions
  • Use stream_for instead of stream_from when possible for automatic scoping
  • Never trust client-side data without validation
  • Consider rate limiting for channels that accept client messages