David has a great video on how to use Action Cable for Rails 5 , for me, I am using the beta 3 version on Rails 5.
The question is, is Action Cable only for a chat app where there is only one parameter passed as data
? Could I pass more than one params to speak
?
RoomChannel (coffee):
App.room = App.cable.subscriptions.create "RoomChannel",
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) ->
alert data['message']
# Called when there's incoming data on the websocket for this channel
speak: (message) -> # Could I pass in more than one params?
@perform 'speak', message: message
room_channel.rb:
# Be sure to restart your server when you modify this file. Action Cable runs in a loop that does not support auto reloading.
class RoomChannel < ApplicationCable::Channel
def subscribed
stream_from "room_channel"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
def speak(data)
ActionCable.server.broadcast 'room_channel', message: data['message']
end
end
If I could pass in more than one params, where would it fit here:
App.room.speak("foo bar"); # one param so far here.
Edit:
I now got an alert of two objects as: [object object]
App.room.speak(
{
data1: "Data 1 mate",
data2: "Data 2 mate"
}
)
room.coffee:
received: (data1, data2) ->
alert data1['message']
room_channel.rb:
def speak(data1, data2)
ActionCable.server.broadcast 'room_channel', message: data1['message'], data2['message']
end
console:
RoomChannel#speak({"message"=>{"data1"=>"Data 1 mate", "data2"=>"Data 2 mate"}})
To pass another param to the actioncable server, you can pass a Javascript Object.
Then on the server side, this Javascript object is represented as a hash.
example:
client side
App.room.speak(
{
param1: "Data 1 mate",
param2: "Data 2 mate"
}
)
server side
def speak(data)
ActionCable.server.broadcast 'room_channel', param1: data['param1'], param2: data['data2']
end
and back to the client
received: (data) ->
alert data['param1']
alert data["param2"]
I guess I can now answer this question. Both params are passed but as an hash. In the console you'll see both params so you'd need to extract the values from message
.
Keep the speak
method as normal:
def speak(data)
ActionCable.server.broadcast 'room_channel', message: data['message']
end
Your receive
function (coffee), should look like this:
received: (data) ->
alert(data.message.data1)
alert(data.message.data2)
You must pass a hash on the broadcast call, for example:
def broadcast_to_room_channel(title, message)
data = { title: title, message: message }
ActionCable.server.broadcast 'room_channel', data
end
I encountered a similar situation, where I needed to pass associated id
params. I used a form_with
helper and data attributes, passing the params through speak to create an instance of a Post
. I found that something like this worked:
view.html.erb
<%= form_with(model: Post.new) do |f| %>
<div>
<%= f.text_area :content,
id: 'text',
data: { first_id: @first.id, second_id: @second.id } %>
</div>
<% end %>
chat_room.coffee
speak: (post) ->
firstId = document.getElementById('text').dataset.firstId
secondId = document.getElementById('text').dataset.secondId
@perform 'speak', post: post, first_id: firstId, second_id: secondId
chat_room_channel.rb
def speak(data)
Post.create! content: data['post'], first_id: data['first_id'], second_id: data['second_id']
end
Riffing on the same video that you referenced, i've moved the broadcast
logic to a worker, where you broadcast your newly created Post
instance to a partial that you access via ApplicationController.renderer
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.