I've been trying to get my head around action cable for what seems like months. Please help.
I have a "Connection" - I can't set the identified_by :current_user
because this endpoint also needs to be consumed by an external API that uses WebSockets. Can't use browser cookies to authenticate the API endpoint.
Files & Support
Connection: /app/channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
end
end
Channel: /app/channels/application_cable/channel.rb
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
I have a specific Visits Channel: /app/channels/visits_channel.rb
class VisitChannel < ApplicationCable::Channel
def subscribed
stream_from "visit_#{params[:visit_id]}"
end
end
Then I have my coffeescript channel: /app/assets/javascripts/channels/visit.coffee
App.visit = App.cable.subscriptions.create { channel: 'VisitChannel', visit_id: '42' },
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) ->
console.log data
push: ->
@perform 'push'
Then I have a callback on my visit model: /app/models/visit.rb
class Visit < ApplicationRecord
after_save :push_to_action_cable
**** detail of model removed ****
def push_to_action_cable
ActionCable.server.broadcast("visit_#{self.id}", self)
end
end
This is working perfectly, it puts to the console the object every time and only that object with an ID of 42
Here is my question:
Within the coffeescript channel: found at /app/assets/javascripts/channels/visit.coffee
- How do I set the visit_id
so that I can "listen" for the changes on only the visit I want?
App.visit = App.cable.subscriptions.create { channel: 'VisitChannel', visit_id: 'HOW_DO_I_SET_THIS?' },
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) ->
console.log data
push: ->
@perform 'push'
What I have tried:
I have tried every variation of things like:
App.visit = App.cable.subscriptions.create { channel: 'VisitChannel', visit_id: <%= @visit.id %> }
results in:
ExecJS::RuntimeError in Visits#action_cable
Showing /Users/johnsalzarulo/code/uvohealth/app/views/layouts/application.html.erb where line #9 raised:
SyntaxError: [stdin]:1:81: unexpected <
and
App.visit = App.cable.subscriptions.create (channel: 'VisitChannel', visit_id: "#{ params[:id] }")
results in:
ExecJS::RuntimeError in Visits#action_cable
Showing /Users/johnsalzarulo/code/uvohealth/app/views/layouts/application.html.erb where line #9 raised:
SyntaxError: [stdin]:1:93: unexpected :
and
App.visit = App.cable.subscriptions.create (channel: 'VisitChannel', visit_id: "#{ @visit.id }")
results in:
visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:4 Uncaught TypeError: Cannot read property 'id' of undefined
at visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:4
at visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:18
(anonymous) @ visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:4
(anonymous) @ visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:18
and
App.visit = App.cable.subscriptions.create (channel: 'VisitChannel', visit_id: "#{ visit.id }")
results in:
visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:4 Uncaught ReferenceError: visit is not defined
at visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:4
at visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:18
(anonymous) @ visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:4
(anonymous) @ visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:18
In Closing
I have tried many many more combinations. The only thing that KIND of works was throwing a <script>
into the view template for that page that explicitly subscribed to the visit, but then I didn't get the benifit of the callbacks, plus I know this isn't the "rails way".
It's been hours of reading these docs and trying to make this work. Can anyone shed some light on what I'm missing here?