Skip to content

Commit

Permalink
Revert "Add Rails >= 5.0.beta3 JSON API params parsing" (#1751)
Browse files Browse the repository at this point in the history
  • Loading branch information
remear committed May 26, 2016
1 parent 94db09b commit 6288203
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 213 deletions.
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Features:
Fixes:
- [#1710](https://github.com/rails-api/active_model_serializers/pull/1710) Prevent association loading when `include_data` option
is set to `false`. (@groyoh)
- [#1747](https://github.com/rails-api/active_model_serializers/pull/1747) Improve jsonapi mime type registration for Rails 5 (@remear)

Misc:
- [#1734](https://github.com/rails-api/active_model_serializers/pull/1734) Adds documentation for conditional attribute (@lambda2)
Expand Down
57 changes: 23 additions & 34 deletions lib/active_model_serializers/register_jsonapi_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,54 +22,43 @@
# render jsonapi: model
#
# No wrapper format needed as it does not apply (i.e. no `wrap_parameters format: [jsonapi]`)

module ActiveModelSerializers::Jsonapi
MEDIA_TYPE = 'application/vnd.api+json'.freeze
HEADERS = {
response: { 'CONTENT_TYPE'.freeze => MEDIA_TYPE },
request: { 'ACCEPT'.freeze => MEDIA_TYPE }
}.freeze

def self.install
# actionpack/lib/action_dispatch/http/mime_types.rb
Mime::Type.register MEDIA_TYPE, :jsonapi

if Rails::VERSION::MAJOR >= 5
ActionDispatch::Request.parameter_parsers[:jsonapi] = parser
else
ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime[:jsonapi]] = parser
end

# ref https://github.com/rails/rails/pull/21496
ActionController::Renderers.add :jsonapi do |json, options|
json = serialize_jsonapi(json, options).to_json(options) unless json.is_a?(String)
self.content_type ||= Mime[:jsonapi]
self.response_body = json
end
end

# Proposal: should actually deserialize the JSON API params
# to the hash format expected by `ActiveModel::Serializers::JSON`
# actionpack/lib/action_dispatch/http/parameters.rb
def self.parser
lambda do |body|
data = JSON.parse(body)
data = { :_json => data } unless data.is_a?(Hash)
data.with_indifferent_access
end
end

module ControllerSupport
def serialize_jsonapi(json, options)
options[:adapter] = :json_api
options.fetch(:serialization_context) do
options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request)
end
options.fetch(:serialization_context) { options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request) }
get_serializer(json, options)
end
end
end

ActiveModelSerializers::Jsonapi.install
# actionpack/lib/action_dispatch/http/mime_types.rb
Mime::Type.register ActiveModelSerializers::Jsonapi::MEDIA_TYPE, :jsonapi

parsers = Rails::VERSION::MAJOR >= 5 ? ActionDispatch::Http::Parameters : ActionDispatch::ParamsParser
media_type = Mime::Type.lookup(ActiveModelSerializers::Jsonapi::MEDIA_TYPE)

# Proposal: should actually deserialize the JSON API params
# to the hash format expected by `ActiveModel::Serializers::JSON`
# actionpack/lib/action_dispatch/http/parameters.rb
parsers::DEFAULT_PARSERS[media_type] = lambda do |body|
data = JSON.parse(body)
data = { :_json => data } unless data.is_a?(Hash)
data.with_indifferent_access
end

# ref https://github.com/rails/rails/pull/21496
ActionController::Renderers.add :jsonapi do |json, options|
json = serialize_jsonapi(json, options).to_json(options) unless json.is_a?(String)
self.content_type ||= media_type
self.response_body = json
end

ActiveSupport.on_load(:action_controller) do
include ActiveModelSerializers::Jsonapi::ControllerSupport
Expand Down
47 changes: 21 additions & 26 deletions test/action_controller/json_api/linked_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
module ActionController
module Serialization
class JsonApi
class LinkedTest < ActionDispatch::IntegrationTest
class LinkedTest < ActionController::TestCase
class LinkedTestController < ActionController::Base
require 'active_model_serializers/register_jsonapi_renderer'
def setup_post
ActionController::Base.cache_store.clear
@role1 = Role.new(id: 1, name: 'admin')
Expand Down Expand Up @@ -38,76 +39,70 @@ def setup_post

def render_resource_without_include
setup_post
render json: @post
render jsonapi: @post
end

def render_resource_with_include
setup_post
render json: @post, adapter: :json_api, include: [:author]
render jsonapi: @post, include: [:author]
end

def render_resource_with_include_of_custom_key_by_original
setup_post
render json: @post, adapter: :json_api, include: [:reviews], serializer: PostWithCustomKeysSerializer
render jsonapi: @post, include: [:reviews], serializer: PostWithCustomKeysSerializer
end

def render_resource_with_nested_include
setup_post
render json: @post, adapter: :json_api, include: [comments: [:author]]
render jsonapi: @post, include: [comments: [:author]]
end

def render_resource_with_nested_has_many_include_wildcard
setup_post
render json: @post, adapter: :json_api, include: 'author.*'
render jsonapi: @post, include: 'author.*'
end

def render_resource_with_missing_nested_has_many_include
setup_post
@post.author = @author2 # author2 has no roles.
render json: @post, adapter: :json_api, include: [author: [:roles]]
render jsonapi: @post, include: [author: [:roles]]
end

def render_collection_with_missing_nested_has_many_include
setup_post
@post.author = @author2
render json: [@post, @post2], adapter: :json_api, include: [author: [:roles]]
render jsonapi: [@post, @post2], include: [author: [:roles]]
end

def render_collection_without_include
setup_post
render json: [@post], adapter: :json_api
render jsonapi: [@post]
end

def render_collection_with_include
setup_post
render json: [@post], adapter: :json_api, include: 'author, comments'
render jsonapi: [@post], include: 'author, comments'
end
end

setup do
@routes = Rails.application.routes.draw do
ActiveSupport::Deprecation.silence do
match ':action', :to => LinkedTestController, via: [:get, :post]
end
end
end
tests LinkedTestController

def test_render_resource_without_include
get '/render_resource_without_include'
get :render_resource_without_include
response = JSON.parse(@response.body)
refute response.key? 'included'
end

def test_render_resource_with_include
get '/render_resource_with_include'
get :render_resource_with_include
response = JSON.parse(@response.body)
assert response.key? 'included'
assert_equal 1, response['included'].size
assert_equal 'Steve K.', response['included'].first['attributes']['name']
end

def test_render_resource_with_nested_has_many_include
get '/render_resource_with_nested_has_many_include_wildcard'
get :render_resource_with_nested_has_many_include_wildcard
response = JSON.parse(@response.body)
expected_linked = [
{
Expand Down Expand Up @@ -149,7 +144,7 @@ def test_render_resource_with_nested_has_many_include
end

def test_render_resource_with_include_of_custom_key_by_original
get '/render_resource_with_include_of_custom_key_by_original'
get :render_resource_with_include_of_custom_key_by_original
response = JSON.parse(@response.body)
assert response.key? 'included'

Expand All @@ -161,33 +156,33 @@ def test_render_resource_with_include_of_custom_key_by_original
end

def test_render_resource_with_nested_include
get '/render_resource_with_nested_include'
get :render_resource_with_nested_include
response = JSON.parse(@response.body)
assert response.key? 'included'
assert_equal 3, response['included'].size
end

def test_render_collection_without_include
get '/render_collection_without_include'
get :render_collection_without_include
response = JSON.parse(@response.body)
refute response.key? 'included'
end

def test_render_collection_with_include
get '/render_collection_with_include'
get :render_collection_with_include
response = JSON.parse(@response.body)
assert response.key? 'included'
end

def test_render_resource_with_nested_attributes_even_when_missing_associations
get '/render_resource_with_missing_nested_has_many_include'
get :render_resource_with_missing_nested_has_many_include
response = JSON.parse(@response.body)
assert response.key? 'included'
refute has_type?(response['included'], 'roles')
end

def test_render_collection_with_missing_nested_has_many_include
get '/render_collection_with_missing_nested_has_many_include'
get :render_collection_with_missing_nested_has_many_include
response = JSON.parse(@response.body)
assert response.key? 'included'
assert has_type?(response['included'], 'roles')
Expand Down

This file was deleted.

1 change: 0 additions & 1 deletion test/support/isolated_unit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@

# These files do not require any others and are needed
# to run the tests
require 'active_support/testing/autorun'
require 'active_support/testing/isolation'

module TestHelpers
Expand Down

0 comments on commit 6288203

Please sign in to comment.