首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ActionCable + Devise + Pundit + ApplicationController.render

ActionCable + Devise + Pundit + ApplicationController.render
EN

Stack Overflow用户
提问于 2016-11-17 04:14:01
回答 2查看 825关注 0票数 2

我正在尝试在通过ActionCable广播的ActionJob中呈现一个模板。

代码语言:javascript
复制
ApplicationController.render(partial: "messages/message", locals: { message: message }, assigns: { current_user: user}).squish

在大多数情况下,这可以很好地工作,但是我的一些模板在视图中使用Punit进行授权。

代码语言:javascript
复制
<% if policy(message).show? %>
  <%= message.body %>
<% end %>

这会在作业运行时引发错误。

代码语言:javascript
复制
ActionView::Template::Error: Devise could not find the `Warden::Proxy` instance on your request environment.

在谷歌上快速搜索一下就会发现这个问题:https://github.com/plataformatec/devise/issues/4271

在工单和链接中提到的,没有环境‘监管人’可用,因为没有执行中间件来添加它。

我该如何解决这个问题呢?

EN

回答 2

Stack Overflow用户

发布于 2016-11-17 04:20:02

作为一种解决方法,以下是我所做的:

代码语言:javascript
复制
class ActiveJobController < ActionController::Base
end

在我的部分中,我没有使用policy帮助器,而是这样做

代码语言:javascript
复制
<% if Pundit::PolicyFinder.new(message).policy.new(current_user, message).show? %>
  <%= message.body %>
<% end %>

从我的ActiveJob

代码语言:javascript
复制
ActiveJobController.render(partial: "messages/message", locals: { message: message, current_user: user }).squish

这就避免了任何引用env["warden"]的股票设计和专家助手。它不是很理想,但现在在请求和作业中都可以使用。

票数 1
EN

Stack Overflow用户

发布于 2020-11-08 03:50:45

另一种可伸缩/可维护的方法是使用助手或视图库,如ViewComponents/cells。通过这种方式,您可以将现有视图提取到组件中,并参数化视图中调用的任何devise/warden方法。这种方法的优点是

  1. 视图更易于测试
  2. 您可以从代码中的任何位置调用它
  3. 没有耦合的依赖项

使用视图助手的示例

假设您在app/views/messages/show.html.erb中具有以下内容

代码语言:javascript
复制
<%= current_user.first_name %>
<%= @message %>

在控制器外部调用MessagesController.render :show将导致错误,因为对请求对象的访问不可用。使用ViewComponents,我们将视图提取到它自己的组件中

app/components/message_component.rb

代码语言:javascript
复制
class MessageComponent < ViewComponent::Base
  def initialize(user:, message:)
    @user = user
    @message = message
  end
end

app/components/message_component.html.erb

代码语言:javascript
复制
<%= @user.first_name %>
<%= @message %>

用法

app/views/messages/show.html.erb中只需调用

代码语言:javascript
复制
<%= render(MessageComponent.new(message: @message, user: current_user) %>

在ActionCable中,它是这样命名的

代码语言:javascript
复制
ApplicationController.render(MessageComponent.new(message: @message, user: current_user)

由于您可以从代码中的任何位置访问ActiveRecord模型,因此应该能够获取@message

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40641472

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档