我正在尝试在通过ActionCable广播的ActionJob中呈现一个模板。
ApplicationController.render(partial: "messages/message", locals: { message: message }, assigns: { current_user: user}).squish在大多数情况下,这可以很好地工作,但是我的一些模板在视图中使用Punit进行授权。
<% if policy(message).show? %>
<%= message.body %>
<% end %>这会在作业运行时引发错误。
ActionView::Template::Error: Devise could not find the `Warden::Proxy` instance on your request environment.在谷歌上快速搜索一下就会发现这个问题:https://github.com/plataformatec/devise/issues/4271
在工单和链接中提到的,没有环境‘监管人’可用,因为没有执行中间件来添加它。
我该如何解决这个问题呢?
发布于 2016-11-17 04:20:02
作为一种解决方法,以下是我所做的:
class ActiveJobController < ActionController::Base
end在我的部分中,我没有使用policy帮助器,而是这样做
<% if Pundit::PolicyFinder.new(message).policy.new(current_user, message).show? %>
<%= message.body %>
<% end %>从我的ActiveJob
ActiveJobController.render(partial: "messages/message", locals: { message: message, current_user: user }).squish这就避免了任何引用env["warden"]的股票设计和专家助手。它不是很理想,但现在在请求和作业中都可以使用。
发布于 2020-11-08 03:50:45
另一种可伸缩/可维护的方法是使用助手或视图库,如ViewComponents/cells。通过这种方式,您可以将现有视图提取到组件中,并参数化视图中调用的任何devise/warden方法。这种方法的优点是
使用视图助手的示例
假设您在app/views/messages/show.html.erb中具有以下内容
<%= current_user.first_name %>
<%= @message %>在控制器外部调用MessagesController.render :show将导致错误,因为对请求对象的访问不可用。使用ViewComponents,我们将视图提取到它自己的组件中
在app/components/message_component.rb中
class MessageComponent < ViewComponent::Base
def initialize(user:, message:)
@user = user
@message = message
end
end在app/components/message_component.html.erb中
<%= @user.first_name %>
<%= @message %>用法
在app/views/messages/show.html.erb中只需调用
<%= render(MessageComponent.new(message: @message, user: current_user) %>在ActionCable中,它是这样命名的
ApplicationController.render(MessageComponent.new(message: @message, user: current_user)由于您可以从代码中的任何位置访问ActiveRecord模型,因此应该能够获取@message
https://stackoverflow.com/questions/40641472
复制相似问题