Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No rendering in 5.1 #405

Open
msimonborg opened this issue Jul 11, 2017 · 4 comments
Open

No rendering in 5.1 #405

msimonborg opened this issue Jul 11, 2017 · 4 comments
Labels

Comments

@msimonborg
Copy link

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.

@nekogami
Copy link

Isn't that normal ? Isn't ActionController::API made so that it's skips a a lot of view rendering inclusion in the controller since it's not supposed to render html ? (which means, no view folder).

wouldn't it be better to convert your view with ActiveModel::Serializers ?

@vsai
Copy link

vsai commented Apr 16, 2018

I personally prefer using Jbuilder over ActiveModel::Serializers. It's a little simpler to maintain different serializations for different rails actions.
I'm running into the same problem where when using ActionController::API, the json response is empty.
But if I include: include ActionView::Rendering, it starts to work correctly.

Using rails 5.1.6.

@ships
Copy link

ships commented Apr 18, 2018

I am also experiencing this or a related issue (it provoked a stack-overflow question) where I was successfully rendering with 5.1.6, but once I started including AccessGranted gem, ActionView::Rendering no longer appears in my ancestry tree for my controller. I'm not enough of a ruby expert to say why the include logic may be changing here, but as far as the class definition goes, the only other change to ancestry is inclusion of AccessGranted::Rails::ControllerMethods.

Your fix above does work for me, however it also seems to introduce complications for controllers with actions that aren't supposed to render with jbuilder.

update

I was able to determine that the gem causing me trouble was loading ActionController::API at file load time (https://github.com/chaps-io/access-granted/blob/master/lib/access-granted.rb#L11-L21), which I believe caused relevant classes to be loaded before Jbuilder could patch ApiController as identified by @msimonborg . For myself I was able to solve this by submitting a PR to that gem which moves that loading logic into a rail tie, but that may not be affordable to all users of Jbuilder.

@gsmetal
Copy link

gsmetal commented May 11, 2018

Looks like duplicate #346

@robin850 robin850 added the bug label Nov 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants