アクションケーブルによるビューのレンダリング
9153 ワード
今週、私はアクションケーブルでWebSocketsの上で部分をレンダリングすることに取り組みました.私は私の認証と認可のライブラリに接続されている問題に遭遇しました.
私のアプリでは、アクションケーブルは、現在のユーザーを識別するために、次のコードを使用します.何か同様の工夫を持つアクションケーブル認証について多くの記事で見つけることができます.
The
あなたは、このポストのトップの近くに気づいたかもしれません
私のアプリでは、アクションケーブルは、現在のユーザーを識別するために、次のコードを使用します.何か同様の工夫を持つアクションケーブル認証について多くの記事で見つけることができます.
# app/channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = env['warden'].user || reject_unauthorized_connection
end
end
end
アクションケーブルでビューをレンダリングするときには、ほとんどの場合、単に現在のユーザーをローカル変数として渡すことができました.# app/channels/my_channel.rb
class MyChannel < ApplicationCable::Channel
def subscribed
stream_for current_user
end
end
<!-- partial_with_local_variable.html.erb -->
Hello <%= current_user.name %>
# any ruby file
MyChannel.broadcast_to(
current_user,
ApplicationController.render(
partial: 'partial_with_local_variable',
locals: { current_user: current_user }
)
)
# => "Hello Brian"
しかし、Cancancanがかかわるとき、ものは毛むくじゃらになります.<!-- partial_with_authorization.html.erb -->
<% if can?(:do_something, to_this_object) %>
Here is the text I want to render.
<% end %>
# Any ruby file
MyChannel.broadcast_to(
current_user,
ApplicationController.render(partial: 'partial_with_authorization')
)
# => ActionView::Template::Error - Devise could not find the `Warden::Proxy` instance on your request environment. Make sure that your application is loading Devise and Warden as expected and that the `Warden::Manager` middleware is present in your middleware stack. If you are seeing this on one of your tests, ensure that your tests are either executing the Rails middleware stack or that your tests are using the `Devise::Test::ControllerHelpers` module to inject the `request.env['warden']` object for you.
その問題はcan?
メソッド.ビューで呼び出されると、そのメソッドの呼び出しチェーンにはcurrent_user
ビューをレンダリングするコントローラのメソッド.このメソッドはコントローラに呼び出されますcurrent_user
ビュー内の変数はこのエラーを防止しません.The
current_user
メソッドは、変数request.env['warden']
HTTPリクエストがWardenミドルウェアを通過した結果として設定します.アクションケーブル通信はHTTPの代わりにWebSocketを介して行われるので、このミドルウェアは使用されず、変数は設定されず、ブロードキャストは失敗する.あなたは、このポストのトップの近くに気づいたかもしれません
env['warden']
で接続します.rbアクションケーブル接続はHTTPリクエストで確立されているので、Wardenミドルウェアを使用し、必要な環境変数がその時存在します.解決策は、そのオブジェクトを接続オブジェクトの属性として格納し、その後、WebSocketの後の通信に必要なときにレンダラに渡すことです.これを行うには、非動作ケーブル固有の記述がありますthis article , しかし、あなたは下記の私の好ましいバージョンを見ることができます.# app/channels/application_cable/connection.rb
# updated from the version at the top of this post.
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
attr_reader :warden
def connect
self.current_user = env['warden'].user || reject_unauthorized_connection
@warden = env['warden'] if current_user
end
end
end
# app/channels/my_channel.rb
# also updated from the earlier example
class MyChannel < ApplicationCable::Channel
def subscribed
stream_for current_user
end
# This method will return ApplicationController.renderer with our Warden::Proxy instance added to the default environment hash.
def renderer
ApplicationController.renderer.tap do |default_renderer|
default_env = default_renderer.instance_variable_get(:@env)
env_with_warden = default_env.merge('warden' => connection.warden)
default_renderer.instance_variable_set(:@env, env_with_warden)
end
end
end
# Any ruby file
MyChannel.broadcast_to(
current_user,
MyChannel.renderer.render(partial: 'partial_with_authorization')
)
# => Here is the text I want to render.
Reference
この問題について(アクションケーブルによるビューのレンダリング), 我々は、より多くの情報をここで見つけました https://dev.to/briankephart/rendering-views-through-action-cable-with-devise-and-cancancan-k38テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol