helper_method 不适用于 ActionCable
Posted
技术标签:
【中文标题】helper_method 不适用于 ActionCable【英文标题】:helper_method not working with ActionCable 【发布时间】:2020-04-21 11:35:24 【问题描述】:我是 Ruby on Rails 的新手,过去 2 个月我一直在尝试了解 ActionCable。
我在
中定义了一个辅助方法 :current_userapp/controllers/application_controller.rb
class ApplicationController < ActionController::Base
helper_method :current_user
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
当从
调用它时app/views/layouts/application.html.erb
<%= current_user.id %>
它显示:例如 1。 但是,当我将 :current_user 带到 Action Cable 时,它显示为空或 nil。
app/channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user
logger.add_tags "ActionCable", "User: #current_user.id"
end
end
end
终端: 成功升级到 WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket) 有一个异常 - NoMethodError(undefined method `id' for nil:NilClass)
在此先感谢您的帮助或指导。
【问题讨论】:
【参考方案1】:如果您看到您提供的文档,您就会知道 identified_by 不是 Channel 实例的方法。它是 Actioncable::Connection 的一种方法。从 Rails 指南 Actioncable 概述中,Connection 类如下所示:
#app/channels/application_cable/connection.rb
module
ApplicationCable class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
private
def find_verified_user
if current_user = User.find_by(id: cookies.signed[:user_id])
current_user
else
reject_unauthorized_connection
end
end
end
end
如您所见,current_user 在此处不可用。相反,您必须在此处创建一个 current_user 连接。 websocket 服务器没有会话,但它可以读取与主应用程序相同的 cookie。所以我想,您需要在身份验证后保存cookie。尽快谢谢..
【讨论】:
感谢大家的帮助和快速澄清@max【参考方案2】:您的 ApplicationController(或一般的控制器)、助手和 ActionCable 之间没有关系。它们是完全不同的概念。
控制器响应常规的 HTTP 请求。它们继承自 ActionController::Base
、ActionController::Api
或 ActionController::Metal
。
Helper 只是位于 app/helpers
目录中的模块,它们包含在视图上下文中。这是控制器提供视图的上下文。当您调用 helper_method :current_user
时,您也可以在控制器中使用该方法。
但 ActionCable 连接不是控制器。它也与控制器或 MVC 没有任何关系。
连接构成了客户端-服务器关系的基础。为了 服务器接受的每个 WebSocket,一个连接对象是 实例化。
Websockets 是一个完全独立于 HTTP 的协议。
虽然您可以将您的助手包含在 Connection 类中,因为它们只是模块,但它不会像 session middleware is not available in ActionCable 一样在这里为您提供帮助。因此,您根据一些教程构建的基于会话的小身份验证不可能神奇地开始在 ActionCable 中工作。
您仍然可以通过cookies.signed
访问 cookie,因此您需要修改您的身份验证系统,以便它设置一个签名的 HTTP cookie,然后您可以在 ActionCable 中读取该 cookie。
【讨论】:
【参考方案3】:仅在您的视图中可用的辅助方法。记住这一点。
【讨论】:
以上是关于helper_method 不适用于 ActionCable的主要内容,如果未能解决你的问题,请参考以下文章
Facebook publish_action 权限不适用于发帖
Android- Intent.ACTION_CALL 不适用于以“911”开头的手机
带有 Intent.VIEW_ACTION 的 Android 安装 apk 不适用于文件提供程序
App Action 适用于 App Actions 测试工具,但不适用于 Google Assistant