我尝试将Devise用于我的Rails应用程序。我可以注册并登录但是当我转到我的其他页面“构建”时,我收到以下错误:
Devise :: MissingWarden in Home#show Devise找不到了 您的请求环境中的
Warden::Proxy
实例。确保这一点 你的应用程序正在按预期加载Devise和Warden 中间件堆栈中存在Warden::Manager
中间件。如果 你在一个测试中看到了这一点,确保你的测试是 要么执行Rails中间件堆栈,要么执行测试 使用Devise::Test::ControllerHelpers
模块注入request.env['warden']
对象。
这是我的控制器:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
private
# Overwriting the sign_out redirect path method
def after_sign_out_path_for(resource_or_scope)
build_path
end
end
这是我的两个部分观点:
<!-- views/devise/menu/_login_items.html.erb -->
<% if user_signed_in? %>
<li>
<%= link_to('Logout', destroy_user_session_path, :method => :delete) %>
</li>
<% else %>
<li>
<%= link_to('Login', new_user_session_path) %>
</li>
<% end %>
和
<!-- views/devise/menu/_registration_items.html.erb -->
<% if user_signed_in? %>
<li>
<%= link_to('Edit registration', edit_user_registration_path) %>
</li>
<% else %>
<li>
<%= link_to('Register', new_user_registration_path) %>
</li>
<% end %>
经过调试,我发现问题来自我的“show”控制器中的这一行:template = HomeController.render('layouts / _template')
感谢您的帮助。
答案 0 :(得分:21)
根据此SO answer,您需要在控制器规范中包含Devise::Test::ControllerHelpers
模块。将以下内容添加到rails_helper:
RSpec.configure do |config|
config.include Devise::Test::ControllerHelpers, type: :controller
end
答案 1 :(得分:3)
添加
config.include Devise::Test::ControllerHelpers, type: :controller
在rails_helper.rb文件中。
答案 2 :(得分:1)
我遇到此错误,在其他任何地方都找不到答案。是在删除并创建数据库之后。但是我没有加载架构。
此问题已解决:
rake db:drop db:create db:schema:load
答案 3 :(得分:1)
我必须在 helper 方法中使用 current_user,因为我正在编写规范。
let(:user) { create(:user) }
before do
allow(helper).to receive(:current_user).and_return(user)
end
但如果您正在处理视图规范,请执行此操作
let(:user) { create(:user) }
before do
allow(view).to receive(:current_user).and_return(user)
end
答案 4 :(得分:0)
好吧,我遇到了同样的问题“设备无法在actioncable中找到看守::代理”,可以通过将当前的user_id
传递给工作中的perform方法来解决,因为您可能正在访问您认为通过广播呈现的当前用户,并且是由于此问题引起的
答案 5 :(得分:0)
测试在某些条件下存在“ current_user”的视图时,我遇到了类似的问题。
我用以下方法解决了它:
let(:user) { FactoryGirl.create :customer }
before(:each) do
allow(view).to receive(:current_user).and_return(user)
...
答案 6 :(得分:0)
未迁移数据库时遇到此错误。下面的命令可以解决问题。
./bin/bundle exec rake db:migrate
答案 7 :(得分:0)
当您尝试通过动作电缆管理某些代码中的Devise current_user
时,可能会发生这种情况。例如后台作业以呈现评论或其他内容。
您可以通过在控制器中使用以下操作来解决此问题,因为您无法在模型或工作级别访问守望者(根据我的有限知识):
(我在CommentsController create操作中创建评论后立即调用作业,该操作调用一个私有方法来呈现一个包含edit和delete按钮的评论部分,为此需要current_user)
def create
@product = Product.find(comment_params[:product_id])
@comment = @product.comments.build(comment_params)
@comment.save!
gon.comment_id = @comment.id
gon.comment_user_id = @comment.user_id
ActionCable.server.broadcast "chat", comment: render_comment
render :create, layout: false
end
def render_comment
CommentsController.renderer.instance_variable_set(:@env, {"HTTP_HOST"=>"localhost:3000",
"HTTPS"=>"off",
"REQUEST_METHOD"=>"GET",
"SCRIPT_NAME"=>"",
"warden" => warden})
CommentsController.render(
partial: 'comments/comment_detail',
locals: {
product: @product,
comment: @comment
}
)
end
这将帮助您解决管理员问题,如果您在该partial中使用了devise的current_user,它将为您提供注释者用户(因为该用户启动了partial的呈现,所以应该如此)。 现在解决此问题,如果您有一个前端框架,则可能需要从cookie中获取当前用户,以限制某些操作,例如编辑/删除。但是,如果您使用的是纯轨,则遇到的解决方案是您必须在具有当前用户ID的dom中创建一个隐藏字段,并且您将获取该ID以在脚本中进行比较。您可能需要使用javascript访问rails变量,因此可以使用 GON gem。 我知道这个答案可能包含的内容远远超出了询问的范围,但是我进行了很多搜索,没有找到一个令人满意的解决方案,请随时讨论。
答案 8 :(得分:0)
如果您在Rspec之外遇到此问题,则表示您试图在ActionCable
通道内渲染视图,可伸缩/可维护的方法是使用助手或类似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