DEV Community

M. E. Patterson
M. E. Patterson

Posted on

Getting Rails ApplicationController.renderer to render images and know about the Rack session

This is going to be a really short one. It took me several hours to figure both of the following tricks out, so I figured I'd share for the next dev who gets stumped like I was.

Let's say you're rendering a chunk of HTML somewhere other than in a view, using Rails ApplicationController.renderer approach. As you might have figured out, this sets up a renderer with a default request environment, which is probably fine for your average partial or whatever.

But I need images!

Right, so, you've noticed that your img tags aren't rendering properly because the default request environment sets up as "example.com" instead of localhost or whatever your actual deployed host might be. So we need to get in there and override some things in our fancy-pants custom renderer:

renderer = ApplicationController.renderer.new(
  http_host: request.host_with_port,
  https: (request.protocol == "https://")
)

renderer.render(
  partial: "widgets/something",
  layout: false
)

This ensures your renderer knows about your current actual request environment's host, port, and protocol, which will enable the img tags to be rendered correctly with proper URLs.

What about the session stuff?

Yeah, so in some weird circumstances, you might have a partial, or a component, and you need it to render in some out-of-band way, maybe using web socket-driven DOM mutations, say, and you need access to all the normal stuff from the Rack session. Here ya go:

renderer = ApplicationController.renderer.new(
  http_host: request.host_with_port,
  https: (request.protocol == "https://"),
  "rack.session": request.session
)

renderer.render(
  partial: "widgets/something",
  layout: false
)

n.b. Depending on your circumstance, you might actually have access to an instantiated legit controller; in this case, you might also get away with this:

controller.render_to_string(
  partial: "widgets/something",
  layout: false
)

...but if you don't have a controller instance, but you do need images and session access, the above trick should help you out!

Discussion (0)