Description
After upgrading my Rails API-only app to 5.1 from ~> 5.0.0 I immediately had issues rendering my Jbuilder templates. The response body would just be blank: ""
I am also using the latest version of Jbuilder
Googling around I found that I was not the only person having this issue. One person suggested an easy fix that worked:
class ApplicationController < ActionController::API
include ActionView::Rendering
...
end
Making sure that one Module was included fixed the problem. Poking around the Jbuilder source code I found some relevant lines in the jbuilder/railtie.rb
class Jbuilder
class Railtie < ::Rails::Railtie
initializer :jbuilder do
...
if Rails::VERSION::MAJOR >= 5
module ::ActionController
module ApiRendering
include ActionView::Rendering
end
end
ActiveSupport.on_load :action_controller do
if self == ActionController::API
include ActionController::Helpers
include ActionController::ImplicitRender
end
end
end
end
...
end
end
This initializer hook should include the needed module in ApiRendering
, which is included in ActionController::API
. This makes sense from an ancestry POV as opposed to including directly into ActionController::API
, and it probably works most of the time, but for whatever reason it's not working for me and a bunch of other people, maybe because of some other configuration or dependency. It seems that since the same initializer hook is including other modules directly into ActionController::API
, we could do that for ActionView::Rendering
, like this:
class Jbuilder
class Railtie < ::Rails::Railtie
initializer :jbuilder do
...
if Rails::VERSION::MAJOR >= 5
# module ::ActionController
# module ApiRendering
# include ActionView::Rendering
# end
# end
ActiveSupport.on_load :action_controller do
if self == ActionController::API
include ActionController::Helpers
include ActionController::ImplicitRender
include ActionView::Rendering
end
end
end
end
...
end
end
I tried out this change locally in my app's gem source code and it works. I also wrote a simple test that checks if the module is included after calling Jbuilder::Railtie.run_initializers
, and the tests pass both the old way and the new way. Unfortunately the old way doesn't work for everyone it seems, this seems more surefire.