How use Aplication.renderer.render from rails 5 with devise
Asked Answered
P

2

8

I want to make my app in real time

This is my error

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.)
1: -if user_signed_in?
2: .ui.popup.computer{id:"post#{post.id}user#{post.user.id}", style:"padding:0px"}
3: .ui.card
4: .image

I don't know what to do

Help me please.

Peculiar answered 24/8, 2016 at 16:40 Comment(1)
I haven't found proper solution yet, but here's some links FYI: evilmartians.com/chronicles/… , thegreatcodeadventure.com/…Scherzo
S
7

I think I found a solution for my case.

Define renderer_with_signed_in_user class method in ApplicationController.

class ApplicationController < ActionController::Base
  ...
  def self.renderer_with_signed_in_user(user)
    ActionController::Renderer::RACK_KEY_TRANSLATION['warden'] ||= 'warden'
    proxy = Warden::Proxy.new({}, Warden::Manager.new({})).tap { |i|
      i.set_user(user, scope: :user, store: false, run_callbacks: false)
    }
    renderer.new('warden' => proxy)
  end
  ...
end

And then you can render from other parts of Rails app, like this:

renderer = ApplicationController.renderer_with_signed_in_user(user)
renderer.render template: 'notifications/show', layout: false, locals: { foo: 'bar' }

Credit to Stefan Wienert for his article

Scherzo answered 23/1, 2018 at 12:15 Comment(0)
A
-1

When you use the new Rails 5 Application Renderer, no middleware is executed. Devise uses Warden and set it as an environnement variable env['warden'], and thus it is missing when you call renderer. That's the reason why you get this error.

To make it work, in your controller simply use before_action for the controller#action that will be rendered to set and pass the instance variable you need to the view.

If you need to check if user is logged in, or use current_user in the rendered view:

class ExamplesController < ApplicationController
  before_action :user_logged_in?, only: :show
  before_action :set_user, only: :show

def show
   # whatever the action does
end

private
  def user_logged_in?
    @user_logged_in = user_signed_in?
  end

  def set_user
    @user = current_user
  end
end

Then in the view ExamplesController#show :

# views/examples/show.html.erb

<%= "Online" if @user_logged_in %>
<%= @user.full_name %>

Hope that helps

Acetaldehyde answered 5/9, 2016 at 21:26 Comment(1)
I think the questioner's problem comes from that trying to render templates outside controller.Scherzo

© 2022 - 2024 — McMap. All rights reserved.