Ruby on Rails 5 Action Cable:当前模型实例的流(基于 URL 的订阅)

Posted

技术标签:

【中文标题】Ruby on Rails 5 Action Cable:当前模型实例的流(基于 URL 的订阅)【英文标题】:Ruby on Rails 5 Action Cable: stream for current model instance (URL-based subscriptions) 【发布时间】:2017-01-03 11:32:13 【问题描述】:

我已经在网络上进行了广泛搜索(包括阅读许多ActionCable 的代码示例),以寻找似乎是一个非常基本问题的答案。唉,我的问题还没解决。

假设,我有一个模型 Search,我已经导航到 URL /searches/1

我还将在javascripts/channels/ 下拥有search.coffee 文件,该文件以:

App.instance = App.cable.subscriptions.create 'SearchChannel'

还有一个看起来像这样的SearchChannel 类:

class SearchChannel < ApplicationCable::Channel
  def subscribed
    search = Search.find(params[:id])
    stream_for search
  end

  def unsubscribed
  end
end

当然,上面的代码会产生错误,因为params[id]nil

这是我的问题:

如何根据 URL 订阅正确的 Search 实例? 如果我在另一个不需要订阅的 URL 上,我如何避免尝试订阅 SearchChannel,例如/searches/1/results?

感谢您的帮助!

【问题讨论】:

您好,如果对您有帮助,请将我的回答标记为正确。 到目前为止,没有任何答案可以帮助我,@VaibhavMaheshwari。 【参考方案1】:

如果您查看ActionCable.Subscriptions#create 的实现,可以通过两种方式调用它。

选项 1(带有频道名称):

App.cable.subscriptions.create 'SearchChannel'

选项 2(带有通道对象):

App.cable.subscriptions.create channel: 'SearchChannel', id: 'Best Room'

如果您使用选项 1,在内部,它会被转换为通道对象。

所以,如果你想在服务器端捕获id,你需要使用第二个选项并传递searchid,那么你应该可以在服务器端捕获它为你描述的:

class SearchChannel < ApplicationCable::Channel
  def subscribed
    search = Search.find(params[:id])
    stream_for search
  end

  def unsubscribed
  end
end

请参阅Client-Server Interactions and Subsciptions 了解更多信息。

【讨论】:

感谢您的回答,但这对我没有帮助。我已经在文档中阅读了有关此选项的信息,但我特别困惑的是如何将 id 发送到 SearchChannel。 Rails 将search.coffee 放在javascripts/channels/ 下,这意味着我需要将id 从某处传递到该文件。这就是我的困难所在。 我不太确定你想通过SearchChannel 订阅实现什么。但是,如果您需要从 ruby​​ 端捕获 @search.id 到 javascript 端,您有多种选择。选项1:当您位于/searches/1 url 时,您可以在javascript 中解析url 并将id 从url 传递给App.cable.subscriptions.create。选项2:在show 模板的头部,将id 存储在javascript 中,例如: 并将search_id 传递给@ 987654343@。希望对您有所帮助。【参考方案2】:

您好,如果您需要从 URL 访问变量以进行服务器端连接处理,您可以执行以下操作。在您的 search.coffee.erb 文件中。

string = window.location.href 
cut_string = "/"
if string.indexOf(cut_string) != -1 
    id = string.split(cut_string)[4]
else
    id = // something else

App.instance = App.cable.subscriptions.create  channel: "SearchChannel" , id: id  , ...

在您的频道文件中,您可以成功使用它。

class SearchChannel < ApplicationCable::Channel
  def subscribed
    search = Search.find(params[:id])
    stream_for search
  end

  def unsubscribed
  end
end

如何根据 URL 订阅正确的 Search 实例?

您可以更改咖啡脚本代码并使其仅在浏览所需页面时创建可操作的连接。

string = window.location.href 
cut_string = "/"
if string.indexOf(cut_string) != -1 
    id = string.split(cut_string)[4] IF BLOCK CREATE CONNECTION
    App.instance = App.cable.subscriptions.create  channel: "SearchChannel" , id: id  , ...

如果我在另一个频道上,如何避免尝试订阅 SearchChannel 不需要订阅的 URL,例如/搜索/1/结果

在咖啡脚本代码的 if 块中添加多个条件。

【讨论】:

以上是关于Ruby on Rails 5 Action Cable:当前模型实例的流(基于 URL 的订阅)的主要内容,如果未能解决你的问题,请参考以下文章

Ruby on Rails:删除多个哈希键

Ruby on Rails 在现有资源上返回 404

在 Ruby on Rails 中使用 Dash `-` 而不是下划线 `_` 的路由

如何在 ruby​​ on rails 中发布数据

mailchimp 邮件程序不能在 ruby​​ on rails 中工作

Ruby on Rails:如何配置设计邮件程序?