Add support for Rails 5 API-only applications (#793)

This commit is contained in:
Cliff Braton 2017-04-03 08:19:42 -05:00 committed by GitHub
parent 2af5f9dd47
commit 05b107b131
3 changed files with 49 additions and 0 deletions

View File

@ -11,6 +11,7 @@ require 'active_support/core_ext/name_error'
require 'draper/version'
require 'draper/configuration'
require 'draper/view_helpers'
require 'draper/compatibility/api_only'
require 'draper/delegation'
require 'draper/automatic_delegation'
require 'draper/finders'
@ -32,6 +33,7 @@ module Draper
def self.setup_action_controller(base)
base.class_eval do
include Draper::Compatibility::ApiOnly if base == ActionController::API
include Draper::ViewContext
extend Draper::HelperSupport
extend Draper::DecoratesAssigned

View File

@ -0,0 +1,23 @@
module Draper
module Compatibility
# Draper expects your `ApplicationController` to include `ActionView::Rendering`. The
# `ApplicationController` generated by Rails 5 API-only applications (created with
# `rails new --api`) don't by default. However, including `ActionView::Rendering` in
# `ApplicatonController` breaks `render :json` due to `render_to_body` being overridden.
#
# This compatibility patch fixes the issue by restoring the original `render_to_body`
# method after including `ActionView::Rendering`. Ultimately, including `ActionView::Rendering`
# in an ActionController::API may not be supported functionality by Rails (see Rails issue
# for more detail: https://github.com/rails/rails/issues/27211). This hack is meant to be a
# temporary solution until we can find a way to not rely on the controller layer.
module ApiOnly
extend ActiveSupport::Concern
included do
alias :previous_render_to_body :render_to_body
include ActionView::Rendering
alias :render_to_body :previous_render_to_body
end
end
end
end

View File

@ -0,0 +1,24 @@
require 'spec_helper'
require 'support/shared_examples/view_helpers'
module Draper
describe Draper do
describe '.setup_action_controller' do
it 'includes api only compatability if base is ActionController::API' do
base = ActionController::API
Draper.setup_action_controller(base)
expect(base.included_modules).to include(Draper::Compatibility::ApiOnly)
end
it 'does not include api only compatibility if base ActionController::Base' do
base = ActionController::Base
Draper.setup_action_controller(base)
expect(base.included_modules).not_to include(Draper::Compatibility::ApiOnly)
end
end
end
end