In my Ruby on Rails project, I have a user
model that is set up by devise. Each user
belongs to an account
with an account_id.
In my application_controller.rb
I have
def set_account
@account = current_user.account
end
This is working fine as in many places of my project I have before_action: set_account
and it does assign @account
correctly.
When a user signs in, I want the user to subscribe to message_notifications_channel_#{account_id}
where account_id
is the id of the account that the user belongs to.
This is how I set up 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
if verified_user = User.find_by(id: cookies.encrypted[:user_id])
verified_user
else
reject_unauthorized_connection
end
end
end
end
When I entered byebug here, User.find_by(id: cookies.encrypted[:user_id])
returned nil and cookies.encrypted[:user_id]
is nil too.
This is the setup for message_notifications_channel.rb
:
class MessageNotificationsChannel < ApplicationCable::Channel
def subscribed
current_user.appear
# stream_from "some_channel"
stream_from "message_notifications_channel_#{params[:account_id]}"
end
def unsubscribed
current_user.disappear
# Any cleanup needed when channel is unsubscribed
end
end
For message_notifications.coffee
, this is the code:
App.message_notifications = App.cable.subscriptions.create {channel: "MessageNotificationsChannel", account_id: current_user.account_id},
connected: ->
# Called when the subscription is ready for use on the server
disconnected: ->
# Called when the subscription has been terminated by the server
received: (data) ->
# Called when there's incoming data on the websocket for this channel
if data['direction'] == 'incoming'
ding = new Audio('/assets/ding.wav');
ding.play();
$('#conversation-messages').append String(data['message']);
if data['direction'] == 'outgoing'
if $('#message_'+data['id']).length == 0
iphone_sms_sent_sound = new Audio('/assets/iphone_send_sms.mp3');
iphone_sms_sent_sound.play();
$('#conversation-messages').append String(data['message']);
else
$('#message_'+data['id']).replaceWith(data['message']);
I'm using the following to broadcast message in the after_create
callback of Message.rb
:
ActionCable.server.broadcast "message_notifications_channel_#{self.account_id}", {id: self.id, direction: self.direction, message: ApplicationController.render(partial:'inbox/message', locals: {message: self})}
This would not work and I got "An unauthorized connection attempt was rejected". I tried using App.message_notifications = App.cable.subscriptions.create {channel: "MessageNotificationsChannel", account_id: @account.id}
This would not work either.
Then I did App.message_notifications = App.cable.subscriptions.create {channel: "MessageNotificationsChannel", account_id: 3}
and commented out current_user.appear
and current_user.disappear
in message_notifications_channel.rb
and everything inside
module ApplicationCable
end
in connection.rb. Then packets will get broadcast and received and things will show up.
How do I get App.message_notifications = App.cable.subscriptions.create {channel: "MessageNotificationsChannel", account_id: },
to use the id of @account.id
or current_user.account_id
while keeping the methods for user verification in connection.rb
?
Thanks!