【问题标题】:how to find model in ActionCable `subscribed` method如何在 ActionCable `subscribed` 方法中查找模型
【发布时间】:2020-03-26 22:50:29
【问题描述】:

我看到很多教程使用subscribed 方法做这样的事情:

class MessagesChannel < ApplicationCable::Channel
 def subscribed
  conversation = Conversation.find(params[:id])
  stream_from "conversation_#{conversation.id}"
 end
end

这个想法是允许多个用户之间进行多次对话。但我不清楚id 参数是如何发送到该方法的。如果我的路由是嵌套的,因此对话 ID 位于 url 中,那么它似乎应该工作。

resources :conversations, only: [:index, :create] do
 resources :messages, only: [:index, :create]
end

但是,上面的频道代码给出了这个错误:

[ActionCable] [user] Registered connection (Z2lkOi8vZnJhY3Rpb25jbHViL1VzZXIvMQ)
[ActionCable] [user] Could not execute command from ({"command"=>"subscribe", "identifier"=>"{\"channel\":\"MessagesChannel\"}"}) [ActiveRecord::RecordNotFound - Couldn't find Conversation without an ID]: /Users/user/.rvm/gems/ruby-2.5.0/gems/activerecord-5.2.0/lib/active_record/relation/finder_methods.rb:431:in `find_with_ids' | /Users/user/.rvm/gems/ruby-2.5.0/gems/activerecord-5.2.0/lib/active_record/relation/finder_methods.rb:69:in `find' | /Users/user/.rvm/gems/ruby-2.5.0/gems/activerecord-5.2.0/lib/active_record/querying.rb:5:in `find' | /Users/user/.rvm/gems/ruby-2.5.0/gems/activerecord-5.2.0/lib/active_record/core.rb:167:in `find' | /Users/user/code/project/app/channels/messages_channel.rb:3:in `subscribed'

如何将对话 ID 传递给 subscribed 方法,以便我的用户可以进行多个私人对话?


更新 1:这是我的 messages.coffee 文件

App.messages = App.cable.subscriptions.create
 channel: "MessagesChannel"
 conversation_id: 1

 connected: ->
  console.log 'Connected'

 disconnected: ->
  console.log 'Disconnected'

 received: (data) ->
  console.log 'Received'
  $('#messages').append(data.message)

 speak: (message, conversation_id) ->
  @perform 'speak', message: message, conversation_id: conversation_id

$(document).on 'turbolinks:load', ->
 submit_message()
 scroll_bottom()

submit_message = () ->
 $('#response').on 'keydown', (event) ->
  if event.keyCode is 13
   App.messages.speak(event.target.value)
   event.target.value = ""
   event.preventDefault()

scroll_bottom = () ->
 $('#messages').scrollTop($('#messages')[0].scrollHeight)

【问题讨论】:

  • 您的 ActionCable 频道与您的路线无关。您的路由响应正常的 HTTP 请求。 Websockets 是它自己的协议。
  • 谢谢!我只在我的代码中包含路线,因为我在网上找到的其他示例在subscribed 中使用params。当用户发送消息时,该参数的 id 存在于 url 中

标签: ruby-on-rails actioncable


【解决方案1】:

这就是我解决这个问题的方式,

在我看来:

<%= form_for Message.new,remote: true,html: {id: 'new-message',multipart: true} do |f| %>
          <%= f.hidden_field :chat_id, value: chat.id,id: 'chat-id' %>
....

注意我给表单的 id,然后是 chat_id 字段。

然后在我的chat.js:

return App.chat = App.cable.subscriptions.create({
      channel: "ChatChannel",
      chat_id: $('#new-message').find('#chat-id').val()
    }

现在我可以像这样在ChatChannel 中使用这个chat_id 参数:

def subscribed
  stream_from "chat_#{params['chat_id']}_channel"
end

编辑:

在你的情况下:

您的 MessagesChannel 订阅操作应如下所示:

def subscribed
 stream_from "conversation_#{params[:conversation_id]}"
end

【讨论】:

  • 我已经用messages.coffee 的代码更新了我的问题(这将是你的chat.js)。我仍然遇到同样的错误。
  • 另外,从chat_channel_for_user_#{current_user.id} 之类的内容流式传输是否更有意义?我希望每个用户都订阅他们参与的所有对话。
  • 我注意到您在 messages.coffee 中将参数 conversation_id 的值设置为 1 但您没有在 MessagesChannel 中读取/使用此参数,而是使用 params[:id] 这是零。将 params[:id] 替换为 params[:conversation_id].. 我已经更新了我的答案..
猜你喜欢
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多