Skip to content

Commit

Permalink
begin playing with using JSON API for deserialization
Browse files Browse the repository at this point in the history
extract key_transfor

chaneg to case_transform gem

fix

tests pass
  • Loading branch information
NullVoxPopuli committed Sep 30, 2016
1 parent 6c6e45b commit 502b691
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 443 deletions.
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ eval_gemfile local_gemfile if File.readable?(local_gemfile)
# Specify your gem's dependencies in active_model_serializers.gemspec
gemspec

# TODO: remove when @beauby re-publishes this gem
gem 'jsonapi', github: 'beauby/jsonapi'

version = ENV['RAILS_VERSION'] || '4.2'

if version == 'master'
Expand Down
1 change: 1 addition & 0 deletions active_model_serializers.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Gem::Specification.new do |spec|
# 'thread_safe'

spec.add_runtime_dependency 'jsonapi', '~> 0.1.1.beta2'
spec.add_runtime_dependency 'case_transform', '>= 0.2'

spec.add_development_dependency 'activerecord', rails_versions
# arel
Expand Down
4 changes: 2 additions & 2 deletions lib/active_model_serializers/adapter/base.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require 'active_model_serializers/key_transform'
require 'case_transform'

module ActiveModelSerializers
module Adapter
Expand Down Expand Up @@ -31,7 +31,7 @@ def self.transform(options)
# @param options [Object] serializable resource options
# @return [Symbol] the default transform for the adapter
def self.transform_key_casing!(value, options)
KeyTransform.send(transform(options), value)
CaseTransform.send(transform(options), value)
end

def self.cache_key
Expand Down
58 changes: 13 additions & 45 deletions lib/active_model_serializers/adapter/json_api/deserialization.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
require 'jsonapi'

module ActiveModelSerializers
module Adapter
class JsonApi
# NOTE(Experimental):
# This is an experimental feature. Both the interface and internals could be subject
# to changes.
module Deserialization
InvalidDocument = Class.new(ArgumentError)

module_function

# Transform a JSON API document, containing a single data object,
Expand Down Expand Up @@ -74,21 +74,21 @@ module Deserialization
#
def parse!(document, options = {})
parse(document, options) do |invalid_payload, reason|
fail InvalidDocument, "Invalid payload (#{reason}): #{invalid_payload}"
fail JSONAPI::Parser::InvalidDocument, "Invalid payload (#{reason}): #{invalid_payload}"
end
end

# Same as parse!, but returns an empty hash instead of raising InvalidDocument
# on invalid payloads.
def parse(document, options = {})
document = document.dup.permit!.to_h if document.is_a?(ActionController::Parameters)

validate_payload(document) do |invalid_document, reason|
yield invalid_document, reason if block_given?
return {}
end
document = JSONAPI.parse(document, options)
document = document.to_hash

primary_data = document['data']

# null data is allowed, as per the JSON API Schema
return {} unless primary_data

attributes = primary_data['attributes'] || {}
attributes['id'] = primary_data['id'] if primary_data['id']
relationships = primary_data['relationships'] || {}
Expand All @@ -101,43 +101,11 @@ def parse(document, options = {})
hash.merge!(parse_relationships(relationships, options))

hash
end

# Checks whether a payload is compliant with the JSON API spec.
#
# @api private
# rubocop:disable Metrics/CyclomaticComplexity
def validate_payload(payload)
unless payload.is_a?(Hash)
yield payload, 'Expected hash'
return
end

primary_data = payload['data']
unless primary_data.is_a?(Hash)
yield payload, { data: 'Expected hash' }
return
end

attributes = primary_data['attributes'] || {}
unless attributes.is_a?(Hash)
yield payload, { data: { attributes: 'Expected hash or nil' } }
return
end

relationships = primary_data['relationships'] || {}
unless relationships.is_a?(Hash)
yield payload, { data: { relationships: 'Expected hash or nil' } }
return
end

relationships.each do |(key, value)|
unless value.is_a?(Hash) && value.key?('data')
yield payload, { data: { relationships: { key => 'Expected hash with :data key' } } }
end
end
rescue JSONAPI::Parser::InvalidDocument
return {} unless block_given?
yield
end
# rubocop:enable Metrics/CyclomaticComplexity

# @api private
def filter_fields(fields, options)
Expand Down Expand Up @@ -205,7 +173,7 @@ def parse_relationships(relationships, options)
# @api private
def transform_keys(hash, options)
transform = options[:key_transform] || :underscore
KeyTransform.send(transform, hash)
CaseTransform.send(transform, hash)
end
end
end
Expand Down
74 changes: 0 additions & 74 deletions lib/active_model_serializers/key_transform.rb

This file was deleted.

6 changes: 3 additions & 3 deletions test/action_controller/json_api/transform_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
module ActionController
module Serialization
class JsonApi
class KeyTransformTest < ActionController::TestCase
class KeyTransformTestController < ActionController::Base
class CaseTransformTest < ActionController::TestCase
class CaseTransformTestController < ActionController::Base
class Post < ::Model; end
class Author < ::Model; end
class TopComment < ::Model; end
Expand Down Expand Up @@ -69,7 +69,7 @@ def render_resource_with_transform_with_global_config
end
end

tests KeyTransformTestController
tests CaseTransformTestController

def test_render_resource_with_transform
get :render_resource_with_transform
Expand Down
Loading

0 comments on commit 502b691

Please sign in to comment.