From 1e839428790a3f2219e24dcea4d996ceeac10a08 Mon Sep 17 00:00:00 2001 From: Lucas Date: Sat, 15 Jul 2017 07:01:11 +0200 Subject: [PATCH] Upgrade to upcoming jsonapi-deserializable version. --- jsonapi-rails.gemspec | 3 +- lib/jsonapi/rails/action_controller.rb | 35 ++++++---- lib/jsonapi/rails/railtie.rb | 14 ---- spec/action_controller_spec.rb | 95 ++++++++++++++++++++------ spec/spec_helper.rb | 2 - 5 files changed, 100 insertions(+), 49 deletions(-) diff --git a/jsonapi-rails.gemspec b/jsonapi-rails.gemspec index 3a38e72..2a6e859 100644 --- a/jsonapi-rails.gemspec +++ b/jsonapi-rails.gemspec @@ -14,7 +14,8 @@ Gem::Specification.new do |spec| spec.files = Dir['README.md', 'lib/**/*'] spec.require_path = 'lib' - spec.add_dependency 'jsonapi-rb', '~> 0.2.1' + spec.add_dependency 'jsonapi-rb', '~> 0.3.0' + spec.add_dependency 'jsonapi-parser', '~> 0.1.0' spec.add_development_dependency 'rails', '~> 5.0' spec.add_development_dependency 'sqlite3' diff --git a/lib/jsonapi/rails/action_controller.rb b/lib/jsonapi/rails/action_controller.rb index 856e2de..746f423 100644 --- a/lib/jsonapi/rails/action_controller.rb +++ b/lib/jsonapi/rails/action_controller.rb @@ -3,6 +3,23 @@ module JSONAPI module Rails + module Deserializable + class Resource < JSONAPI::Deserializable::Resource + id + type + attributes + has_one do |_rel, id, type, key| + type = type.to_s.singularize.camelize + { "#{key}_id".to_sym => id, "#{key}_type".to_sym => type } + end + has_many do |_rel, ids, types, key| + key = key.to_s.singularize + types = types.map { |t| t.to_s.singularize.camelize } + { "#{key}_ids".to_sym => ids, "#{key}_types".to_sym => types } + end + end + end + module ActionController extend ActiveSupport::Concern @@ -10,22 +27,14 @@ module ActionController class_methods do def deserializable_resource(key, options = {}, &block) - _deserializable(key, options, - JSONAPI::Deserializable::Resource, &block) - end - - def deserializable_relationship(key, options = {}, &block) - _deserializable(key, options, - JSONAPI::Deserializable::Relationship, &block) - end - - # @api private - def _deserializable(key, options, fallback, &block) options = options.dup - klass = options.delete(:class) || Class.new(fallback, &block) + klass = options.delete(:class) || + Class.new(JSONAPI::Rails::Deserializable::Resource, &block) before_action(options) do |controller| - resource = klass.new(controller.params[:_jsonapi].to_unsafe_hash) + hash = controller.params[:_jsonapi].to_unsafe_hash + JSONAPI::Parser::Resource.parse!(hash) + resource = klass.new(hash[:data]) controller.request.env[JSONAPI_POINTERS_KEY] = resource.reverse_mapping controller.params[key.to_sym] = resource.to_hash diff --git a/lib/jsonapi/rails/railtie.rb b/lib/jsonapi/rails/railtie.rb index b37d523..4653642 100644 --- a/lib/jsonapi/rails/railtie.rb +++ b/lib/jsonapi/rails/railtie.rb @@ -41,20 +41,6 @@ class Railtie < ::Rails::Railtie RENDERERS[:jsonapi_error].render(errors, options).to_json end - - JSONAPI::Deserializable::Resource.configure do |config| - config.default_has_one do |key, _rel, id, type| - key = key.to_s.singularize - type = type.to_s.singularize.camelize - { "#{key}_id".to_sym => id, "#{key}_type".to_sym => type } - end - - config.default_has_many do |key, _rel, ids, types| - key = key.to_s.singularize - types = types.map { |t| t.to_s.singularize.camelize } - { "#{key}_ids".to_sym => ids, "#{key}_types".to_sym => types } - end - end end end end diff --git a/spec/action_controller_spec.rb b/spec/action_controller_spec.rb index 7c3842f..54e7a5b 100644 --- a/spec/action_controller_spec.rb +++ b/spec/action_controller_spec.rb @@ -2,39 +2,96 @@ describe ActionController::Base, type: :controller do describe '.deserializable_resource' do - controller do - deserializable_resource :user - - def create - render plain: 'ok' - end - end - let(:payload) do { _jsonapi: { 'data' => { 'type' => 'users', - 'attributes' => { 'foo' => 'bar', 'bar' => 'baz' } + 'attributes' => { 'name' => 'Lucas' } } } } end - it 'makes the deserialized resource available in params' do - post :create, params: payload + context 'when using default deserializer' do + controller do + deserializable_resource :user + + def create + render plain: 'ok' + end + end + + it 'makes the deserialized resource available in params' do + post :create, params: payload + + expected = { 'type' => 'users', 'name' => 'Lucas' } + expect(controller.params[:user]).to eq(expected) + end + + it 'makes the deserialization mapping available via #jsonapi_pointers' do + post :create, params: payload + + expected = { name: '/data/attributes/name', + type: '/data/type' } + expect(controller.jsonapi_pointers).to eq(expected) + end + end + + context 'when using a customized deserializer' do + controller do + deserializable_resource :user do + attribute(:name) do |val| + { 'first_name'.to_sym => val } + end + end + + def create + render plain: 'ok' + end + end - expected = { 'type' => 'users', 'foo' => 'bar', 'bar' => 'baz' } - expect(controller.params[:user]).to eq(expected) + it 'makes the deserialized resource available in params' do + post :create, params: payload + + expected = { 'type' => 'users', 'first_name' => 'Lucas' } + expect(controller.params[:user]).to eq(expected) + end + + it 'makes the deserialization mapping available via #jsonapi_pointers' do + post :create, params: payload + + expected = { first_name: '/data/attributes/name', + type: '/data/type' } + expect(controller.jsonapi_pointers).to eq(expected) + end end - it 'makes the deserialization mapping available via #jsonapi_pointers' do - post :create, params: payload + context 'when using a customized deserializer with key_format' do + controller do + deserializable_resource :user do + key_format(&:capitalize) + end - expected = { foo: '/data/attributes/foo', - bar: '/data/attributes/bar', - type: '/data/type' } - expect(controller.jsonapi_pointers).to eq(expected) + def create + render plain: 'ok' + end + end + + it 'makes the deserialized resource available in params' do + post :create, params: payload + + expected = { 'type' => 'users', 'Name' => 'Lucas' } + expect(controller.params[:user]).to eq(expected) + end + + it 'makes the deserialization mapping available via #jsonapi_pointers' do + post :create, params: payload + + expected = { Name: '/data/attributes/name', + type: '/data/type' } + expect(controller.jsonapi_pointers).to eq(expected) + end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b015803..8f698be 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,3 @@ -require 'jsonapi/parser' - # This file was generated by the `rails generate rspec:install` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause