helper_method 无法使用 ActionCable

helper_method not working with ActionCable

我是 Rails 上 Ruby 的新手,过去 2 个月我一直在努力了解 ActionCable。

我在

中定义了一个辅助方法 :current_user

app/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:升级,HTTP_UPGRADE:websocket) 出现异常 - NoMethodError(nil:NilClass 的未定义方法“id”)

在此先感谢您的帮助或指导。

如果您看到您提供的文档,您就会知道 identified_by 不是 Channel 实例的方法。它是 Actioncable::Connection 的一种方法。来自 Rails Actioncable 概述指南,这是连接 class 的样子:

#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。尽快谢谢..

您的 ApplicationController(或一般控制器)、助手和 ActionCable 之间没有任何关系。它们是完全不同的概念。

控制器响应常规 HTTP 请求。它们继承自 ActionController::BaseActionController::ApiActionController::Metal

助手只是位于 app/helpers 目录中的模块,它们包含在视图上下文中。这是控制器提供视图的上下文。当您调用 helper_method :current_user 时,您也可以在控制器中使用该方法。

但是 ActionCable 连接不是控制器。它也与控制器或 MVC 没有任何关系。

Connections form the foundation of the client-server relationship. For every WebSocket accepted by the server, a connection object is instantiated.

Websockets 是一个完全独立于 HTTP 的协议。

虽然您可以将您的助手包含在连接 class 中,因为它们只是模块,但它不会像 session middleware is not available in ActionCable 那样为您提供帮助。因此,您根据一些教程构建的基于小会话的身份验证不可能神奇地开始在 ActionCable 中工作。

您仍然可以通过 cookies.signed 访问 cookie,因此您需要做的是修改您的身份验证系统,以便它设置一个签名的 HTTP cookie,然后您可以在 ActionCable 中读取它。

辅助方法仅在您的视图中可用。记住这一点。