Rails 4.2.6按用户区分ActionCable通知及路由报错问题
Hey there! Let’s work through your Action Cable issues step by step—first fixing that constant error, then getting user-specific notifications up and running.
1. Fixing the "uninitialized constant ActionCable" Error
The root of this issue is that Action Cable isn’t built into Rails 4.2.x (it became a core feature starting with Rails 5). Since you’re using the actioncable gem, you need to make sure it’s properly loaded in your app:
- First, double-check your
Gemfileincludes the gem and runbundle install:# Gemfile gem 'actioncable' - Next, explicitly require Action Cable in your
config/application.rb—Rails 4 won’t auto-load it by default:# config/application.rb require File.expand_path('../boot', __FILE__) require 'rails/all' require 'action_cable' # Add this line Bundler.require(*Rails.groups) # ... rest of your application.rb code - Make sure you’ve created a
config/cable.ymlfile with basic adapter settings (even for development):# config/cable.yml development: adapter: async test: adapter: async production: adapter: redis url: redis://localhost:6379/1 - Finally, restart your Rails server—gem dependencies won’t load until you do this. The
mount ActionCable.server => '/cable'route should work now.
2. Implementing User-Specific Notifications
To send notifications only to the intended user, you’ll need to tie each user to their own unique Action Cable stream. Here’s how to set it up:
Step 1: Identify Users in the Cable Connection
First, ensure Action Cable knows which user is connected. Update your connection file to authenticate users:
# 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 # Adjust this to match your auth setup (e.g., Devise uses env['warden'].user) if current_user = User.find_by(id: cookies.signed[:user_id]) current_user else reject_unauthorized_connection end end end end
Step 2: Create a Notifications Channel with User-Specific Streams
Build a channel that subscribes each user to their own unique notification stream:
# app/channels/notifications_channel.rb class NotificationsChannel < ApplicationCable::Channel def subscribed # Stream notifications to a user-specific channel (e.g., "notifications_123" for user ID 123) stream_from "notifications_#{current_user.id}" end def unsubscribed # Clean up streams when the user disconnects stop_all_streams end end
Step 3: Broadcast Notifications to the Right User
When you generate a notification (e.g., in a controller or model), broadcast it to the target user’s stream:
# Example: In a NotificationsController#create action def create @notification = Notification.new(notification_params) if @notification.save # Send the notification to the recipient's stream ActionCable.server.broadcast "notifications_#{@notification.user_id}", message: @notification.content, timestamp: @notification.created_at.strftime("%H:%M"), url: notification_url(@notification) end redirect_to notifications_path end
Step 4: Listen for Notifications in the Frontend
Add JavaScript to subscribe to the channel and display incoming notifications:
// app/assets/javascripts/cable.js // Make sure you've included Action Cable's JS in your asset pipeline: //= require action_cable (function() { this.App || (this.App = {}); // Connect to the Action Cable server App.cable = ActionCable.createConsumer('/cable'); // Subscribe to the notifications channel App.notifications = App.cable.subscriptions.create('NotificationsChannel', { received: function(data) { // Update your UI with the new notification (adjust selector to match your page) $('#notifications-list').prepend(` <li> <a href="${data.url}">${data.message}</a> <small>${data.timestamp}</small> </li> `); } }); }).call(this);
Quick Troubleshooting for Unmentioned Errors
If you run into other issues, check these first:
- Verify all channel files are in the
app/channels/directory (Rails won’t pick them up elsewhere). - Check your server logs (
log/development.log) for detailed error messages—they’ll often point to issues like auth failures or missing stream names. - For production, ensure Redis is installed and running (the async adapter only works for development/test).
内容的提问来源于stack exchange,提问作者Fernando Aureliano

