Rails_ai_agents action-cable-patterns

install
source · Clone the upstream repo
git clone https://github.com/ThibautBaissac/rails_ai_agents
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ThibautBaissac/rails_ai_agents "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/action-cable-patterns" ~/.claude/skills/thibautbaissac-rails-ai-agents-action-cable-patterns && rm -rf "$T"
manifest: .claude/skills/action-cable-patterns/SKILL.md
source content

Action Cable Patterns for Rails 8

Overview

Action Cable integrates WebSockets with Rails:

  • Real-time updates without polling
  • Server-to-client push notifications
  • Chat and messaging features
  • Live dashboards and feeds
  • Collaborative editing

Quick Start

Action Cable is included in Rails by default. Configure it:

# config/cable.yml
development:
  adapter: async

test:
  adapter: test

production:
  adapter: solid_cable  # Rails 8 default
  # OR
  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") %>

Project Structure

app/
├── channels/
│   ├── application_cable/
│   │   ├── connection.rb      # Authentication
│   │   └── channel.rb         # Base channel
│   ├── notifications_channel.rb
│   ├── events_channel.rb
│   └── chat_channel.rb
├── javascript/
│   └── channels/
│       ├── consumer.js
│       ├── notifications_channel.js
│       └── events_channel.js
spec/channels/
├── notifications_channel_spec.rb
└── events_channel_spec.rb

Connection Authentication

# 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
      # Using Rails 8 authentication
      if session_token = cookies.signed[:session_token]
        if session = Session.find_by(token: session_token)
          session.user
        else
          reject_unauthorized_connection
        end
      else
        reject_unauthorized_connection
      end
    end
  end
end

Channel Patterns

Four core patterns are available. See channel-patterns.md for full Ruby and JavaScript implementations:

  • Pattern 1: Notifications Channel — streams per-user notifications via
    stream_for current_user
  • Pattern 2: Resource Updates Channel — streams updates for a specific resource with authorization via
    reject
  • Pattern 3: Chat Channel — bidirectional messaging with
    speak
    and
    typing
    actions, presence tracking
  • Pattern 4: Dashboard Live Updates — broadcasts stats and activity feed to all account members

Each pattern follows the same structure:

  1. subscribed
    — find the resource, check authorization, call
    stream_for
  2. Class-level
    broadcast_*
    methods — render partials via
    ApplicationController.renderer
  3. A matching JavaScript subscription handler with a
    received(data)
    switch

Broadcasting

Broadcasting can be triggered from services, models, or callbacks. See broadcasting-and-stimulus.md for:

  • From a service object — call
    EventsChannel.broadcast_update(event)
    after persistence
  • From model callbacks — use
    after_create_commit
    to trigger channel broadcasts
  • Turbo Streams integration — use
    broadcast_append_to
    /
    broadcast_remove_to
    helpers directly on models
  • Stimulus controller — wrap the Action Cable subscription lifecycle inside a Stimulus controller for clean connect/disconnect management
  • Performance patterns — connection limits, selective broadcasting, debounced broadcasts

Testing Channels

See testing.md for full specs. Key conventions:

# Stub connection identity
stub_connection(current_user: user)

# Assert subscription confirmed and streaming
subscribe(event_id: event.id)
expect(subscription).to be_confirmed
expect(subscription).to have_stream_for(event)

# Assert rejection for unauthorized access
expect(subscription).to be_rejected

# Assert broadcast payload
expect {
  described_class.notify(user, notification)
}.to have_broadcasted_to(user).with(hash_including(type: "notification"))

Checklist

  • Connection authentication configured
  • Channel authorization implemented
  • Client-side subscription set up
  • Broadcasting from services/models
  • Channel specs written
  • Error handling in place
  • Reconnection logic on client
  • Performance limits configured

References

  • channel-patterns.md — Full implementations of Notifications, Resource Updates, Chat, and Dashboard channels (Ruby + JavaScript)
  • broadcasting-and-stimulus.md — Broadcasting from services/models, Turbo Streams integration, Stimulus controller, performance tips
  • testing.md — RSpec channel specs, authorization specs, and system tests