简体   繁体   中英

More than one params with Rails 5 Action Cable

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM