This blog is part of our Rails 5 series.
Rails request-response cycle is very easy to understand.
A request hits the app, a route is matched to a controller action from
and finally controller action processes the request and renders HTML or JSON based
on the type of the request.
But sometimes we want to render our HTML or JSON response outside of this request-response cycle.
For example let’s say user is allowed to download PDF version of a report on web. This can be done using request-response cycle. We also need to send a weekly report to managers and the email should have the report as an attachment. Now we need to generate the same PDF but since emails are sent using background job the request-response cycle is missing.
Rails 5 has this feature baked in.
Let’s say we have a
we want to render individual order outside of controller.
rails console and execute following command.
This will render
@order set to
Order.last. Instance variables can be set using
assigns in the same way
we use them in controller actions.
Those instance variables will be passed to
the view that is going to be rendered.
Rendering partials is also possible.
This will render
app/views/orders/_form.html.erb and will pass
order as local
Say I want to render all orders, but in JSON format.
Even rendering simple text is possible.
text, we can also use
render file and
A typical web request carries it’s own environment with it. We usually handle
this environment using
request.env in controllers.
Certain gems like
devise depends on
env hash for information such as warden token.
So when we are rendering outside of controller, we need to make sure that the rendering happens with correct environment.
Rails provides a default rack environment for this purpose.
The default options used
can be accessed through
Internally, Rails will build a new Rack environment based on these options.
Customizing the environment
We can customize environment using method
Let’s say that we need “method as post” and we want
“https to be true” for our background job processing.
Now that we have our custom
renderer we can use it to generate view.
Overall this is a nice feature which enables reuse of existing code.