jsonapi-rails 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 29c73976a2fb4451e84ad275247518ed54bfe660
4
- data.tar.gz: 58417d63bcfc17109fce8a6e8527ef1324c234e8
3
+ metadata.gz: c4ddfbba5b18351a7d69d74537a47c821e717397
4
+ data.tar.gz: 79ec8e0be87a8aa3110e0e927b449fbf46e85ce6
5
5
  SHA512:
6
- metadata.gz: ef952c74fbf3c00e06ce25bfc7775ff92faf25c59fd080b64a9ceec0755ba5235e8f883986f411e24bf664de0ad22fcd947ddd49492f2b6fb0c435f379c042c8
7
- data.tar.gz: 03b7cd4763b50cab7a90e357216f21fe7df4f2c892271896e76710d4e3fc084c4a7ceabdfd4e11d4cea988422a64ccb752146de9b6cb41d206eed0d9ab1c6e2f
6
+ metadata.gz: 8d2958f2136d6a613ade5d7a713dbfa7d12f4d6d233a1e23f119b2d8a2fd57d8052c9d821a2993b1377b6fa843b250cc4bf59b5205fcb345cdd98de7851083fd
7
+ data.tar.gz: e42703a777344cc33da29a6a2ccae04f68f58c4fdcf399d5e20fedc30a7033c9646941aa2bd1b5712756e008999f11c2a782ffb1438f5c82fa6ac1300f9007c6
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Generates an initializer for jsonapi-rails.
3
+
4
+ Example:
5
+ `rails generate jsonapi:initializer`
@@ -0,0 +1,7 @@
1
+ class InitializerGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('../templates', __FILE__)
3
+
4
+ def copy_initializer_file
5
+ copy_file 'initializer.rb', 'config/initializers/jsonapi.rb'
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ JSONAPI::Rails.configure do |config|
2
+ # # Set a default serializable class mapping.
3
+ # config.jsonapi_class = Hash.new { |h, k|
4
+ # names = k.to_s.split('::')
5
+ # klass = names.pop
6
+ # h[k] = [*names, "Serializable#{klass}"].join('::').safe_constantize
7
+ # }
8
+ #
9
+ # # Set a default serializable class mapping for errors.
10
+ # config.jsonapi_errors_class = Hash.new { |h, k|
11
+ # names = k.to_s.split('::')
12
+ # klass = names.pop
13
+ # h[k] = [*names, "Serializable#{klass}"].join('::').safe_constantize
14
+ # }.tap { |h|
15
+ # h[:'ActiveModel::Errors'] = JSONAPI::Rails::SerializableActiveModelErrors
16
+ # h[:Hash] = JSONAPI::Rails::SerializableErrorHash
17
+ # }
18
+ #
19
+ # # Set a default JSON API object.
20
+ # config.jsonapi_object = {
21
+ # version: '1.0'
22
+ # }
23
+ #
24
+ # # Set default exposures.
25
+ # config.jsonapi_expose = {
26
+ # url_helpers: ::Rails.application.routes.url_helpers
27
+ # }
28
+ #
29
+ # # Set a default pagination scheme.
30
+ # config.jsonapi_pagination = ->(_) { nil }
31
+ end
@@ -0,0 +1,45 @@
1
+ require 'jsonapi/rails/serializable_active_model_errors'
2
+ require 'jsonapi/rails/serializable_error_hash'
3
+
4
+ module JSONAPI
5
+ module Rails
6
+ class Configuration < ActiveSupport::InheritableOptions; end
7
+ DEFAULT_JSONAPI_CLASS = Hash.new do |h, k|
8
+ names = k.to_s.split('::')
9
+ klass = names.pop
10
+ h[k] = [*names, "Serializable#{klass}"].join('::').safe_constantize
11
+ end.freeze
12
+
13
+ DEFAULT_JSONAPI_ERRORS_CLASS = DEFAULT_JSONAPI_CLASS.dup.merge!(
14
+ 'ActiveModel::Errors'.to_sym =>
15
+ JSONAPI::Rails::SerializableActiveModelErrors,
16
+ 'Hash'.to_sym => JSONAPI::Rails::SerializableErrorHash
17
+ ).freeze
18
+
19
+ DEFAULT_JSONAPI_OBJECT = {
20
+ version: '1.0'
21
+ }.freeze
22
+
23
+ DEFAULT_JSONAPI_EXPOSE = {
24
+ url_helpers: ::Rails.application.routes.url_helpers
25
+ }.freeze
26
+
27
+ DEFAULT_JSONAPI_PAGINATION = ->(_) { nil }
28
+
29
+ DEFAULT_CONFIG = {
30
+ jsonapi_class: DEFAULT_JSONAPI_CLASS,
31
+ jsonapi_errors_class: DEFAULT_JSONAPI_ERRORS_CLASS,
32
+ jsonapi_object: DEFAULT_JSONAPI_OBJECT,
33
+ jsonapi_expose: DEFAULT_JSONAPI_EXPOSE,
34
+ jsonapi_pagination: DEFAULT_JSONAPI_PAGINATION
35
+ }.freeze
36
+
37
+ def self.configure
38
+ yield config
39
+ end
40
+
41
+ def self.config
42
+ @config ||= JSONAPI::Rails::Configuration.new(DEFAULT_CONFIG)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,126 @@
1
+ require 'jsonapi/deserializable'
2
+ require 'jsonapi/parser'
3
+ require 'jsonapi/rails/configuration'
4
+
5
+ module JSONAPI
6
+ module Rails
7
+ module Deserializable
8
+ # @private
9
+ class Resource < JSONAPI::Deserializable::Resource
10
+ id
11
+ type
12
+ attributes
13
+ has_one do |_rel, id, type, key|
14
+ type = type.to_s.singularize.camelize
15
+ { "#{key}_id".to_sym => id, "#{key}_type".to_sym => type }
16
+ end
17
+ has_many do |_rel, ids, types, key|
18
+ key = key.to_s.singularize
19
+ types = types.map { |t| t.to_s.singularize.camelize }
20
+ { "#{key}_ids".to_sym => ids, "#{key}_types".to_sym => types }
21
+ end
22
+ end
23
+ end
24
+
25
+ # ActionController methods and hooks for JSON API deserialization and
26
+ # rendering.
27
+ module Controller
28
+ extend ActiveSupport::Concern
29
+
30
+ JSONAPI_POINTERS_KEY = 'jsonapi-rails.jsonapi_pointers'.freeze
31
+
32
+ class_methods do
33
+ # Declare a deserializable resource.
34
+ #
35
+ # @param key [Symbol] The key under which the deserialized hash will be
36
+ # available within the `params` hash.
37
+ # @param options [Hash]
38
+ # @option class [Class] A custom deserializer class. Optional.
39
+ # @option only List of actions for which deserialization should happen.
40
+ # Optional.
41
+ # @option except List of actions for which deserialization should not
42
+ # happen. Optional.
43
+ # @yieldreturn Optional block for in-line definition of custom
44
+ # deserializers.
45
+ #
46
+ # @example
47
+ # class ArticlesController < ActionController::Base
48
+ # deserializable_resource :article, only: [:create, :update]
49
+ #
50
+ # def create
51
+ # article = Article.new(params[:article])
52
+ #
53
+ # if article.save
54
+ # render jsonapi: article
55
+ # else
56
+ # render jsonapi_errors: article.errors
57
+ # end
58
+ # end
59
+ #
60
+ # # ...
61
+ # end
62
+ #
63
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
64
+ def deserializable_resource(key, options = {}, &block)
65
+ options = options.dup
66
+ klass = options.delete(:class) ||
67
+ Class.new(JSONAPI::Rails::Deserializable::Resource, &block)
68
+
69
+ before_action(options) do |controller|
70
+ # TODO(lucas): Fail with helpful error message if _jsonapi not
71
+ # present.
72
+ hash = controller.params[:_jsonapi].to_unsafe_hash
73
+ ActiveSupport::Notifications
74
+ .instrument('parse.jsonapi', payload: hash, class: klass) do
75
+ JSONAPI::Parser::Resource.parse!(hash)
76
+ resource = klass.new(hash[:data])
77
+ controller.request.env[JSONAPI_POINTERS_KEY] =
78
+ resource.reverse_mapping
79
+ controller.params[key.to_sym] = resource.to_hash
80
+ end
81
+ end
82
+ end
83
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
84
+ end
85
+
86
+ # Hook for serializable class mapping (for resources).
87
+ # Overridden by the `class` renderer option.
88
+ # @return [Hash{Symbol=>Class}]
89
+ def jsonapi_class
90
+ JSONAPI::Rails.config[:jsonapi_class]
91
+ end
92
+
93
+ # Hook for serializable class mapping (for errors).
94
+ # Overridden by the `class` renderer option.
95
+ # @return [Hash{Symbol=>Class}]
96
+ def jsonapi_errors_class
97
+ JSONAPI::Rails.config[:jsonapi_errors_class]
98
+ end
99
+
100
+ # Hook for the jsonapi object.
101
+ # Overridden by the `jsonapi_object` renderer option.
102
+ # @return [Hash]
103
+ def jsonapi_object
104
+ JSONAPI::Rails.config[:jsonapi_object]
105
+ end
106
+
107
+ # Hook for default exposures.
108
+ # @return [Hash]
109
+ def jsonapi_expose
110
+ JSONAPI::Rails.config[:jsonapi_expose]
111
+ end
112
+
113
+ # Hook for pagination scheme.
114
+ # @return [Hash]
115
+ def jsonapi_pagination(resources)
116
+ instance_exec(resources, &JSONAPI::Rails.config[:jsonapi_pagination])
117
+ end
118
+
119
+ # JSON pointers for deserialized fields.
120
+ # @return [Hash{Symbol=>String}]
121
+ def jsonapi_pointers
122
+ request.env[JSONAPI_POINTERS_KEY] || {}
123
+ end
124
+ end
125
+ end
126
+ end
@@ -2,61 +2,66 @@ require 'rails/railtie'
2
2
  require 'action_controller'
3
3
  require 'active_support'
4
4
 
5
- require 'jsonapi/rails/parser'
6
5
  require 'jsonapi/rails/renderer'
7
6
 
8
7
  module JSONAPI
9
8
  module Rails
9
+ # @private
10
10
  class Railtie < ::Rails::Railtie
11
11
  MEDIA_TYPE = 'application/vnd.api+json'.freeze
12
+ PARSER = lambda do |body|
13
+ data = JSON.parse(body)
14
+ hash = { _jsonapi: data }
15
+
16
+ hash.with_indifferent_access
17
+ end
12
18
  RENDERERS = {
13
- jsonapi: SuccessRenderer.new,
14
- jsonapi_error: ErrorsRenderer.new
19
+ jsonapi: SuccessRenderer.new,
20
+ jsonapi_errors: ErrorsRenderer.new
15
21
  }.freeze
16
22
 
17
- initializer 'jsonapi-rails.action_controller' do
23
+ initializer 'jsonapi-rails.init' do
24
+ register_mime_type
25
+ register_parameter_parser
26
+ register_renderers
18
27
  ActiveSupport.on_load(:action_controller) do
19
- require 'jsonapi/rails/action_controller'
20
- include ::JSONAPI::Rails::ActionController
21
-
22
- Mime::Type.register MEDIA_TYPE, :jsonapi
23
-
24
- if ::Rails::VERSION::MAJOR >= 5
25
- ::ActionDispatch::Request.parameter_parsers[:jsonapi] = PARSER
26
- else
27
- ::ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime[:jsonapi]] = PARSER
28
- end
28
+ require 'jsonapi/rails/controller'
29
+ include ::JSONAPI::Rails::Controller
30
+ end
31
+ end
29
32
 
30
- ::ActionController::Renderers.add(:jsonapi) do |resources, options|
31
- self.content_type ||= Mime[:jsonapi]
33
+ private
32
34
 
33
- RENDERERS[:jsonapi].render(resources, options).to_json
34
- end
35
-
36
- ::ActionController::Renderers.add(:jsonapi_error) do |errors, options|
37
- # Renderer proc is evaluated in the controller context, so it
38
- # has access to the jsonapi_pointers method.
39
- options = options.merge(_jsonapi_pointers: jsonapi_pointers)
40
- self.content_type ||= Mime[:jsonapi]
35
+ def register_mime_type
36
+ Mime::Type.register(MEDIA_TYPE, :jsonapi)
37
+ end
41
38
 
42
- RENDERERS[:jsonapi_error].render(errors, options).to_json
43
- end
39
+ def register_parameter_parser
40
+ if ::Rails::VERSION::MAJOR >= 5
41
+ ActionDispatch::Request.parameter_parsers[:jsonapi] = PARSER
42
+ else
43
+ ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime[:jsonapi]] = PARSER
44
+ end
45
+ end
44
46
 
45
- JSONAPI::Deserializable::Resource.configure do |config|
46
- config.default_has_one do |key, _rel, id, type|
47
- key = key.to_s.singularize
48
- type = type.to_s.singularize.camelize
49
- { "#{key}_id".to_sym => id, "#{key}_type".to_sym => type }
50
- end
47
+ # rubocop:disable Metrics/MethodLength
48
+ def register_renderers
49
+ ActiveSupport.on_load(:action_controller) do
50
+ RENDERERS.each do |name, renderer|
51
+ ::ActionController::Renderers.add(name) do |resources, options|
52
+ # Renderer proc is evaluated in the controller context.
53
+ self.content_type ||= Mime[:jsonapi]
51
54
 
52
- config.default_has_many do |key, _rel, ids, types|
53
- key = key.to_s.singularize
54
- types = types.map { |t| t.to_s.singularize.camelize }
55
- { "#{key}_ids".to_sym => ids, "#{key}_types".to_sym => types }
55
+ ActiveSupport::Notifications.instrument('render.jsonapi',
56
+ resources: resources,
57
+ options: options) do
58
+ renderer.render(resources, options, self).to_json
59
+ end
56
60
  end
57
61
  end
58
62
  end
59
63
  end
64
+ # rubocop:enable Metrics/MethodLength
60
65
  end
61
66
  end
62
67
  end
@@ -2,36 +2,63 @@ require 'jsonapi/serializable/renderer'
2
2
 
3
3
  module JSONAPI
4
4
  module Rails
5
+ # @private
5
6
  class SuccessRenderer
6
- def initialize(renderer = JSONAPI::Serializable::SuccessRenderer.new)
7
+ def initialize(renderer = JSONAPI::Serializable::Renderer.new)
7
8
  @renderer = renderer
8
9
 
9
10
  freeze
10
11
  end
11
12
 
12
- def render(resources, options)
13
- opts = options.dup
14
- # TODO(beauby): Move this to a global configuration.
15
- default_exposures = {
16
- url_helpers: ::Rails.application.routes.url_helpers
17
- }
18
- opts[:expose] = default_exposures.merge!(opts[:expose] || {})
19
- opts[:jsonapi] = opts.delete(:jsonapi_object)
13
+ def render(resources, options, controller)
14
+ options = default_options(options, controller, resources)
20
15
 
21
- @renderer.render(resources, opts)
16
+ @renderer.render(resources, options)
17
+ end
18
+
19
+ private
20
+
21
+ def default_options(options, controller, resources)
22
+ options.dup.tap do |opts|
23
+ opts[:class] ||= controller.jsonapi_class
24
+ if (pagination_links = controller.jsonapi_pagination(resources))
25
+ opts[:links] = (opts[:links] || {}).merge(pagination_links)
26
+ end
27
+ opts[:expose] = controller.jsonapi_expose.merge(opts[:expose] || {})
28
+ opts[:jsonapi] = opts.delete(:jsonapi_object) ||
29
+ controller.jsonapi_object
30
+ end
22
31
  end
23
32
  end
24
33
 
34
+ # @private
25
35
  class ErrorsRenderer
26
- def initialize(renderer = JSONAPI::Serializable::ErrorsRenderer.new)
36
+ def initialize(renderer = JSONAPI::Serializable::Renderer.new)
27
37
  @renderer = renderer
28
38
 
29
39
  freeze
30
40
  end
31
41
 
32
- def render(errors, options)
33
- # TODO(beauby): SerializableError inference on AR validation errors.
34
- @renderer.render(errors, options)
42
+ def render(errors, options, controller)
43
+ options = default_options(options, controller)
44
+
45
+ errors = [errors] unless errors.is_a?(Array)
46
+
47
+ @renderer.render_errors(errors, options)
48
+ end
49
+
50
+ private
51
+
52
+ def default_options(options, controller)
53
+ options.dup.tap do |opts|
54
+ opts[:class] ||= controller.jsonapi_errors_class
55
+ opts[:expose] =
56
+ controller.jsonapi_expose
57
+ .merge(opts[:expose] || {})
58
+ .merge!(_jsonapi_pointers: controller.jsonapi_pointers)
59
+ opts[:jsonapi] = opts.delete(:jsonapi_object) ||
60
+ controller.jsonapi_object
61
+ end
35
62
  end
36
63
  end
37
64
  end
@@ -0,0 +1,38 @@
1
+ module JSONAPI
2
+ module Rails
3
+ # @private
4
+ class SerializableActiveModelError < Serializable::Error
5
+ title do
6
+ "Invalid #{@field}" unless @field.nil?
7
+ end
8
+
9
+ detail do
10
+ @message
11
+ end
12
+
13
+ source do
14
+ pointer @pointer unless @pointer.nil?
15
+ end
16
+ end
17
+
18
+ # @private
19
+ class SerializableActiveModelErrors
20
+ def initialize(exposures)
21
+ @errors = exposures[:object]
22
+ @reverse_mapping = exposures[:_jsonapi_pointers] || {}
23
+
24
+ freeze
25
+ end
26
+
27
+ def as_jsonapi
28
+ @errors.keys.flat_map do |key|
29
+ @errors.full_messages_for(key).map do |message|
30
+ SerializableActiveModelError.new(field: key, message: message,
31
+ pointer: @reverse_mapping[key])
32
+ .as_jsonapi
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ module JSONAPI
2
+ module Rails
3
+ # @private
4
+ class SerializableErrorHash < JSONAPI::Serializable::Error
5
+ def initialize(exposures)
6
+ super
7
+ exposures[:object].each do |k, v|
8
+ instance_variable_set("@_#{k}", v)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Hosseini
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-22 00:00:00.000000000 Z
11
+ date: 2017-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jsonapi-rb
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.1
19
+ version: 0.5.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.1
26
+ version: 0.5.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: jsonapi-parser
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rails
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,20 @@ dependencies:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
96
  version: '3.5'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  description: Efficient, convenient, non-intrusive JSONAPI framework for Rails.
84
112
  email:
85
113
  - lucas.hosseini@gmail.com
@@ -88,14 +116,19 @@ extensions: []
88
116
  extra_rdoc_files: []
89
117
  files:
90
118
  - README.md
119
+ - lib/generators/jsonapi/initializer/USAGE
120
+ - lib/generators/jsonapi/initializer/initializer_generator.rb
121
+ - lib/generators/jsonapi/initializer/templates/initializer.rb
91
122
  - lib/generators/jsonapi/serializable/USAGE
92
123
  - lib/generators/jsonapi/serializable/serializable_generator.rb
93
124
  - lib/generators/jsonapi/serializable/templates/serializable.rb.erb
94
125
  - lib/jsonapi/rails.rb
95
- - lib/jsonapi/rails/action_controller.rb
96
- - lib/jsonapi/rails/parser.rb
126
+ - lib/jsonapi/rails/configuration.rb
127
+ - lib/jsonapi/rails/controller.rb
97
128
  - lib/jsonapi/rails/railtie.rb
98
129
  - lib/jsonapi/rails/renderer.rb
130
+ - lib/jsonapi/rails/serializable_active_model_errors.rb
131
+ - lib/jsonapi/rails/serializable_error_hash.rb
99
132
  homepage: https://github.com/jsonapi-rb/jsonapi-rails
100
133
  licenses:
101
134
  - MIT
@@ -116,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
149
  version: '0'
117
150
  requirements: []
118
151
  rubyforge_project:
119
- rubygems_version: 2.6.12
152
+ rubygems_version: 2.6.13
120
153
  signing_key:
121
154
  specification_version: 4
122
155
  summary: jsonapi-rb integrations for Rails.
@@ -1,41 +0,0 @@
1
- require 'jsonapi/deserializable'
2
- require 'jsonapi/parser'
3
-
4
- module JSONAPI
5
- module Rails
6
- module ActionController
7
- extend ActiveSupport::Concern
8
-
9
- JSONAPI_POINTERS_KEY = 'jsonapi_deserializable.jsonapi_pointers'.freeze
10
-
11
- class_methods do
12
- def deserializable_resource(key, options = {}, &block)
13
- _deserializable(key, options,
14
- JSONAPI::Deserializable::Resource, &block)
15
- end
16
-
17
- def deserializable_relationship(key, options = {}, &block)
18
- _deserializable(key, options,
19
- JSONAPI::Deserializable::Relationship, &block)
20
- end
21
-
22
- # @api private
23
- def _deserializable(key, options, fallback, &block)
24
- options = options.dup
25
- klass = options.delete(:class) || Class.new(fallback, &block)
26
-
27
- before_action(options) do |controller|
28
- resource = klass.new(controller.params[:_jsonapi].to_unsafe_hash)
29
- controller.request.env[JSONAPI_POINTERS_KEY] =
30
- resource.reverse_mapping
31
- controller.params[key.to_sym] = resource.to_hash
32
- end
33
- end
34
- end
35
-
36
- def jsonapi_pointers
37
- request.env[JSONAPI_POINTERS_KEY]
38
- end
39
- end
40
- end
41
- end
@@ -1,12 +0,0 @@
1
- require 'jsonapi/deserializable'
2
-
3
- module JSONAPI
4
- module Rails
5
- PARSER = lambda do |body|
6
- data = JSON.parse(body)
7
- hash = { _jsonapi: data }
8
-
9
- hash.with_indifferent_access
10
- end
11
- end
12
- end