【问题标题】:helper_method not working with ActionCablehelper_method 不适用于 ActionCable
【发布时间】:2020-04-21 11:35:24
【问题描述】:

我是 Ruby on Rails 的新手,过去 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: Upgrade, HTTP_UPGRADE: websocket) 有一个异常 - NoMethodError(undefined method `id' for nil:NilClass)

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

【问题讨论】:

    标签: ruby-on-rails actioncable


    【解决方案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::BaseActionController::ApiActionController::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】:

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

      【讨论】:

        猜你喜欢
        • 2019-07-27
        • 2018-01-06
        • 1970-01-01
        • 2011-10-13
        • 2014-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多