Using Rails 5 new renderer with Clearance and Devise

on under developer
1 minute read

Rendering partials with the new Rails 5 ActionController::Renderer provides a nice shortcut to render templates outside the normal controller flow without defining own proxy classes. This is useful for a variety of use cases, like pushing partials down a MessageBus pipe to frontend or mobile, or PDF generation with WicketPDF.
But to access authentication stuff, like Clearance/Devise (current_user) or CanCan (current_ability) is not obvious, as the whole controller environment and middlewares are missing.

Here, I am using Clearance, which needs to store it's authentication stuff in the rack request env under the key :clearance. (tested with Rails 5.0.0.beta3)


Unfortunately, at the moment there is no direct access to the env from the ApplicationController.renderer.render method. We need to initialize the renderer manually and even need to whitelist the rack key name :clearance (otherwise, it will be replaced with nil atm).

class ApplicationController < ActionController::Base
  def self.render_with_signed_in_user(user, *args)
    ActionController::Renderer::RACK_KEY_TRANSLATION[:clearance] ||= :clearance
    renderer_class = self.renderer
    session ={}).tap{|i| i.sign_in(user) }
    renderer = session)

Use it like:

ApplicationController.render_with_signed_in_user(user, 'posts/post', locals: { post: @post })


Solving the same problem with Devise 4.0.0.rc2

ActionView::Template::Error: undefined method `authenticate' for nil:NilClass
        from ../gems/devise-4.0.0.rc2/lib/devise/controllers/helpers.rb:124:in `current_user'
        from ../gems/actionpack-5.0.0.beta3/lib/abstract_controller/helpers.rb:67:in `current_user'

We solve that in a similar way by initializing a Warden Proxy:

 def self.render_with_signed_in_user(user, *args)
   ActionController::Renderer::RACK_KEY_TRANSLATION['warden'] ||= 'warden'
   proxy ={},{})).tap{|i| i.set_user(user, scope: :user) }
   renderer ='warden' => proxy)

Backported New Renderer

Using the backport_new_renderer Gem for Rails 4.2 is a little different, as the class api is deviated from Rails master: Assign the env directly through a acessor.

  def self.render_with_signed_in_user(user, *args)
    renderer =
    renderer.env[:clearance] ={}).tap{|i| i.sign_in(user) }

In this blog article there are also some tips for general debugging & access full url from rendered partials