这是我发现的将 Pundit 与 Activecable 结合使用的解决方案。
首先我们需要访问用户模型。您可以按照Action Cable Overview - Connection Setup 中的说明进行操作。主要是需要修改connection.rb中的代码
# 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 verified_user = User.find_by(id: cookies.encrypted[:user_id])
verified_user
else
reject_unauthorized_connection
end
end
end
end
注意:您可能需要使用不同的方式来查找您的用户。我正在使用 devise_token_auth,因此需要将 uid、token 和 client_id 传递给 connection.rb,然后通过以下代码获取用户:
if user && user.valid_token?(token, client_id)
user
else
reject_unauthorized_connection
end
我提到这一点只是因为您获取用户的方式可能会有所不同。主要是你需要使用identified_by current_user 并设置它。
我没有立即在文档中找到的另一件事是,您的频道现在可以访问 current_user。由于用户名可能与您的 pundit_user 名不同,我发现此时手动将用户传递给 Pundit 最容易。所以在订阅我的频道文件时,我有这个代码:
def subscribed
message = MessagePolicy::Scope.new(self.current_user, Project).resolve.find(params[:message])
stream_for message
end
您当然也可以通过这种方式手动授权,而不是使用 Scope:
MessagePolicy.new(self.current_user, message).show?