ApplicationController.render – one more way for a CSRF token to annoy you.

CSRF token and ActionController::InvalidAuthenticityToken” could be some of the most annoying issues in a rails application. Here is one more way you could get annoyed, and it is rarely the rails fault.

ApplicationController.render

The method allows us to render rails partials outside of the views and controllers. It is useful for things like rendering a view in a delayed job. There is no request context there, no session and yet sometimes you would like to render a view in a job.

I think it was introduced in Rails 5 and we’ve been using it here and there.

ApplicationController.render for a json response.

We are using Datatables-net and we generate a JSON response that contains some HTML that should be visualized to the user. The HTML is a button_to for a delete form. In the table for our groups we had a remove action. This remove action is actually a form for an HTTP delete request.

The form has a token

It turns out that the token generated in the context of ApplicationController.render is invalid. There is no session passed to ApplicationController. We should have just used ‘render’ – the method available in the views.

The correct fragment was

   def generate_remove_button_for record
-    rendered_string = ApplicationController.render(
+    rendered_string = render(
       partial: 'shared/fc/admin_unify/table_actions',
+      formats: [:html],
       locals: { 
         links: get_edit_delete_actions([*@namespaces, record]),
         id: record.to_param