jsonapi-rails 0.3.1 → 0.4.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 +5 -5
- data/lib/generators/jsonapi/initializer/templates/initializer.rb +46 -1
- data/lib/generators/jsonapi/serializable/serializable_generator.rb +10 -2
- data/lib/generators/jsonapi/serializable/templates/serializable.rb.erb +1 -1
- data/lib/jsonapi/rails.rb +10 -1
- data/lib/jsonapi/rails/configuration.rb +51 -29
- data/lib/jsonapi/rails/controller.rb +4 -117
- data/lib/jsonapi/rails/controller/deserialization.rb +83 -0
- data/lib/jsonapi/rails/controller/hooks.rb +75 -0
- data/lib/jsonapi/rails/deserializable_resource.rb +21 -0
- data/lib/jsonapi/rails/log_subscriber.rb +25 -0
- data/lib/jsonapi/rails/logging.rb +10 -0
- data/lib/jsonapi/rails/railtie.rb +2 -3
- data/lib/jsonapi/rails/renderer.rb +12 -4
- metadata +22 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d405b930bc2fa8afb813fc3ab4632b3b3badad3650dc0ef812dbb5696a5e1998
|
4
|
+
data.tar.gz: ac9a0458233bd902d06996b1576d4e5bf4ee649914a363f55da6c22c206de198
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5481077f3a4c79df726f33a338c5961b746ad5764a3644ded49d9f85b4b4c09340f1bc43300b433aa61828973a71e736e81dad3d9ca354cb1986721462d87a7f
|
7
|
+
data.tar.gz: '054339d8e7b084229d01da3d70a19e68f904b38e88c32d23c13337950e4c30cd77ae86a744b4636c483bdd5d5458666d381952e284e465eb58417cbc91bb8b0e'
|
@@ -21,12 +21,57 @@ JSONAPI::Rails.configure do |config|
|
|
21
21
|
# version: '1.0'
|
22
22
|
# }
|
23
23
|
#
|
24
|
+
# # Set default cache.
|
25
|
+
# # A lambda/proc that will be eval'd in the controller context.
|
26
|
+
# config.jsonapi_cache = ->() { nil }
|
27
|
+
#
|
28
|
+
# # Uncomment the following to enable fragment caching. Make sure you
|
29
|
+
# # invalidate cache keys accordingly.
|
30
|
+
# config.jsonapi_cache = lambda {
|
31
|
+
# Rails.cache
|
32
|
+
# }
|
33
|
+
#
|
24
34
|
# # Set default exposures.
|
25
35
|
# # A lambda/proc that will be eval'd in the controller context.
|
26
36
|
# config.jsonapi_expose = lambda {
|
27
37
|
# { url_helpers: ::Rails.application.routes.url_helpers }
|
28
38
|
# }
|
29
39
|
#
|
40
|
+
# # Set default fields.
|
41
|
+
# # A lambda/proc that will be eval'd in the controller context.
|
42
|
+
# config.jsonapi_fields = ->() { nil }
|
43
|
+
#
|
44
|
+
# # Uncomment the following to have it default to the `fields` query
|
45
|
+
# # parameter.
|
46
|
+
# config.jsonapi_fields = lambda {
|
47
|
+
# fields_param = params.to_unsafe_hash.fetch(:fields, {})
|
48
|
+
# Hash[fields_param.map { |k, v| [k.to_sym, v.split(',').map!(&:to_sym)] }]
|
49
|
+
# }
|
50
|
+
#
|
51
|
+
# # Set default include.
|
52
|
+
# # A lambda/proc that will be eval'd in the controller context.
|
53
|
+
# config.jsonapi_include = ->() { nil }
|
54
|
+
#
|
55
|
+
# # Uncomment the following to have it default to the `include` query
|
56
|
+
# # parameter.
|
57
|
+
# config.jsonapi_include = lambda {
|
58
|
+
# params[:include]
|
59
|
+
# }
|
60
|
+
#
|
61
|
+
# # Set default links.
|
62
|
+
# # A lambda/proc that will be eval'd in the controller context.
|
63
|
+
# config.jsonapi_links = ->() { {} }
|
64
|
+
#
|
65
|
+
# # Set default meta.
|
66
|
+
# # A lambda/proc that will be eval'd in the controller context.
|
67
|
+
# config.jsonapi_meta = ->() { nil }
|
68
|
+
#
|
30
69
|
# # Set a default pagination scheme.
|
31
|
-
# config.jsonapi_pagination = ->(_) {
|
70
|
+
# config.jsonapi_pagination = ->(_) { {} }
|
71
|
+
#
|
72
|
+
# # Set a logger.
|
73
|
+
# config.logger = Logger.new(STDOUT)
|
74
|
+
#
|
75
|
+
# # Uncomment the following to disable logging.
|
76
|
+
# config.logger = Logger.new('/dev/null')
|
32
77
|
end
|
@@ -8,18 +8,26 @@ module Jsonapi
|
|
8
8
|
def copy_serializable_file
|
9
9
|
template 'serializable.rb.erb',
|
10
10
|
File.join('app/serializable', class_path,
|
11
|
-
"
|
11
|
+
"#{serializable_file_name}.rb")
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
+
def serializable_file_name
|
17
|
+
"serializable_#{file_name}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def serializable_class_name
|
21
|
+
(class_path + [serializable_file_name]).map!(&:camelize).join("::")
|
22
|
+
end
|
23
|
+
|
16
24
|
def model_klass
|
17
25
|
# TODO(beauby): Ensure the model class exists.
|
18
26
|
class_name.safe_constantize
|
19
27
|
end
|
20
28
|
|
21
29
|
def type
|
22
|
-
model_klass.
|
30
|
+
model_klass.model_name.plural
|
23
31
|
end
|
24
32
|
|
25
33
|
def attr_names
|
data/lib/jsonapi/rails.rb
CHANGED
@@ -1,4 +1,13 @@
|
|
1
1
|
require 'jsonapi/deserializable'
|
2
2
|
require 'jsonapi/serializable'
|
3
|
-
require 'jsonapi/rails/configuration'
|
4
3
|
require 'jsonapi/rails/railtie'
|
4
|
+
|
5
|
+
module JSONAPI
|
6
|
+
module Rails
|
7
|
+
require 'jsonapi/rails/configuration'
|
8
|
+
require 'jsonapi/rails/logging'
|
9
|
+
|
10
|
+
extend Configurable
|
11
|
+
extend Logging
|
12
|
+
end
|
13
|
+
end
|
@@ -4,42 +4,64 @@ require 'jsonapi/rails/serializable_error_hash'
|
|
4
4
|
module JSONAPI
|
5
5
|
module Rails
|
6
6
|
class Configuration < ActiveSupport::InheritableOptions; end
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
|
8
|
+
# @private
|
9
|
+
module Configurable
|
10
|
+
DEFAULT_JSONAPI_CLASS = Hash.new do |h, k|
|
11
|
+
names = k.to_s.split('::')
|
12
|
+
klass = names.pop
|
13
|
+
h[k] = [*names, "Serializable#{klass}"].join('::').safe_constantize
|
14
|
+
end.freeze
|
15
|
+
|
16
|
+
DEFAULT_JSONAPI_ERRORS_CLASS = DEFAULT_JSONAPI_CLASS.dup.merge!(
|
17
|
+
'ActiveModel::Errors'.to_sym =>
|
15
18
|
JSONAPI::Rails::SerializableActiveModelErrors,
|
16
|
-
|
17
|
-
|
19
|
+
'Hash'.to_sym => JSONAPI::Rails::SerializableErrorHash
|
20
|
+
).freeze
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
DEFAULT_JSONAPI_OBJECT = {
|
23
|
+
version: '1.0'
|
24
|
+
}.freeze
|
22
25
|
|
23
|
-
|
24
|
-
{ url_helpers: ::Rails.application.routes.url_helpers }
|
25
|
-
}.freeze
|
26
|
+
DEFAULT_JSONAPI_CACHE = ->() { nil }
|
26
27
|
|
27
|
-
|
28
|
+
DEFAULT_JSONAPI_EXPOSE = lambda {
|
29
|
+
{ url_helpers: ::Rails.application.routes.url_helpers }
|
30
|
+
}
|
28
31
|
|
29
|
-
|
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
|
32
|
+
DEFAULT_JSONAPI_FIELDS = ->() { nil }
|
36
33
|
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
DEFAULT_JSONAPI_INCLUDE = ->() { nil }
|
35
|
+
|
36
|
+
DEFAULT_JSONAPI_LINKS = ->() { {} }
|
37
|
+
|
38
|
+
DEFAULT_JSONAPI_META = ->() { nil }
|
39
|
+
|
40
|
+
DEFAULT_JSONAPI_PAGINATION = ->(_) { {} }
|
41
|
+
|
42
|
+
DEFAULT_LOGGER = Logger.new(STDERR)
|
43
|
+
|
44
|
+
DEFAULT_CONFIG = {
|
45
|
+
jsonapi_class: DEFAULT_JSONAPI_CLASS,
|
46
|
+
jsonapi_errors_class: DEFAULT_JSONAPI_ERRORS_CLASS,
|
47
|
+
jsonapi_cache: DEFAULT_JSONAPI_CACHE,
|
48
|
+
jsonapi_expose: DEFAULT_JSONAPI_EXPOSE,
|
49
|
+
jsonapi_fields: DEFAULT_JSONAPI_FIELDS,
|
50
|
+
jsonapi_include: DEFAULT_JSONAPI_INCLUDE,
|
51
|
+
jsonapi_links: DEFAULT_JSONAPI_LINKS,
|
52
|
+
jsonapi_meta: DEFAULT_JSONAPI_META,
|
53
|
+
jsonapi_object: DEFAULT_JSONAPI_OBJECT,
|
54
|
+
jsonapi_pagination: DEFAULT_JSONAPI_PAGINATION,
|
55
|
+
logger: DEFAULT_LOGGER
|
56
|
+
}.freeze
|
57
|
+
|
58
|
+
def configure
|
59
|
+
yield config
|
60
|
+
end
|
40
61
|
|
41
|
-
|
42
|
-
|
62
|
+
def config
|
63
|
+
@config ||= JSONAPI::Rails::Configuration.new(DEFAULT_CONFIG)
|
64
|
+
end
|
43
65
|
end
|
44
66
|
end
|
45
67
|
end
|
@@ -1,126 +1,13 @@
|
|
1
|
-
require 'jsonapi/
|
2
|
-
require 'jsonapi/
|
3
|
-
require 'jsonapi/rails/configuration'
|
1
|
+
require 'jsonapi/rails/controller/deserialization'
|
2
|
+
require 'jsonapi/rails/controller/hooks'
|
4
3
|
|
5
4
|
module JSONAPI
|
6
5
|
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
6
|
# ActionController methods and hooks for JSON API deserialization and
|
26
7
|
# rendering.
|
27
8
|
module Controller
|
28
|
-
|
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].dup
|
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].dup
|
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
|
-
instance_exec(&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
|
9
|
+
include Deserialization
|
10
|
+
include Hooks
|
124
11
|
end
|
125
12
|
end
|
126
13
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'jsonapi/parser'
|
2
|
+
require 'jsonapi/rails/deserializable_resource'
|
3
|
+
|
4
|
+
module JSONAPI
|
5
|
+
module Rails
|
6
|
+
module Controller
|
7
|
+
# Controller class and instance methods for deserialization of incoming
|
8
|
+
# JSON API payloads.
|
9
|
+
module Deserialization
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
JSONAPI_POINTERS_KEY = 'jsonapi-rails.jsonapi_pointers'.freeze
|
13
|
+
|
14
|
+
class_methods do
|
15
|
+
# Declare a deserializable resource.
|
16
|
+
#
|
17
|
+
# @param key [Symbol] The key under which the deserialized hash will be
|
18
|
+
# available within the `params` hash.
|
19
|
+
# @param options [Hash]
|
20
|
+
# @option class [Class] A custom deserializer class. Optional.
|
21
|
+
# @option only List of actions for which deserialization should happen.
|
22
|
+
# Optional.
|
23
|
+
# @option except List of actions for which deserialization should not
|
24
|
+
# happen. Optional.
|
25
|
+
# @yieldreturn Optional block for in-line definition of custom
|
26
|
+
# deserializers.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# class ArticlesController < ActionController::Base
|
30
|
+
# deserializable_resource :article, only: [:create, :update]
|
31
|
+
#
|
32
|
+
# def create
|
33
|
+
# article = Article.new(params[:article])
|
34
|
+
#
|
35
|
+
# if article.save
|
36
|
+
# render jsonapi: article
|
37
|
+
# else
|
38
|
+
# render jsonapi_errors: article.errors
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # ...
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
46
|
+
def deserializable_resource(key, options = {}, &block)
|
47
|
+
options = options.dup
|
48
|
+
klass = options.delete(:class) ||
|
49
|
+
Class.new(JSONAPI::Rails::DeserializableResource, &block)
|
50
|
+
|
51
|
+
before_action(options) do |controller|
|
52
|
+
hash = controller.params.to_unsafe_hash[:_jsonapi]
|
53
|
+
if hash.nil?
|
54
|
+
JSONAPI::Rails.logger.warn do
|
55
|
+
"Unable to deserialize #{key} because no JSON API payload was" \
|
56
|
+
" found. (#{controller.controller_name}##{params[:action]})"
|
57
|
+
end
|
58
|
+
next
|
59
|
+
end
|
60
|
+
|
61
|
+
ActiveSupport::Notifications
|
62
|
+
.instrument('parse.jsonapi-rails',
|
63
|
+
key: key, payload: hash, class: klass) do
|
64
|
+
JSONAPI::Parser::Resource.parse!(hash)
|
65
|
+
resource = klass.new(hash[:data])
|
66
|
+
controller.request.env[JSONAPI_POINTERS_KEY] =
|
67
|
+
resource.reverse_mapping
|
68
|
+
controller.params[key.to_sym] = resource.to_hash
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
73
|
+
end
|
74
|
+
|
75
|
+
# JSON pointers for deserialized fields.
|
76
|
+
# @return [Hash{Symbol=>String}]
|
77
|
+
def jsonapi_pointers
|
78
|
+
request.env[JSONAPI_POINTERS_KEY] || {}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'jsonapi/rails/configuration'
|
2
|
+
|
3
|
+
module JSONAPI
|
4
|
+
module Rails
|
5
|
+
module Controller
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
# Hooks for customizing rendering default options at controller-level.
|
9
|
+
module Hooks
|
10
|
+
# Hook for serializable class mapping (for resources).
|
11
|
+
# Overridden by the `class` renderer option.
|
12
|
+
# @return [Hash{Symbol=>Class}]
|
13
|
+
def jsonapi_class
|
14
|
+
JSONAPI::Rails.config[:jsonapi_class].dup
|
15
|
+
end
|
16
|
+
|
17
|
+
# Hook for serializable class mapping (for errors).
|
18
|
+
# Overridden by the `class` renderer option.
|
19
|
+
# @return [Hash{Symbol=>Class}]
|
20
|
+
def jsonapi_errors_class
|
21
|
+
JSONAPI::Rails.config[:jsonapi_errors_class].dup
|
22
|
+
end
|
23
|
+
|
24
|
+
# Hook for the jsonapi object.
|
25
|
+
# Overridden by the `jsonapi_object` renderer option.
|
26
|
+
# @return [Hash,nil]
|
27
|
+
def jsonapi_object
|
28
|
+
JSONAPI::Rails.config[:jsonapi_object]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Hook for default exposures.
|
32
|
+
# @return [Hash]
|
33
|
+
def jsonapi_expose
|
34
|
+
instance_exec(&JSONAPI::Rails.config[:jsonapi_expose])
|
35
|
+
end
|
36
|
+
|
37
|
+
# Hook for default cache.
|
38
|
+
# @return [#fetch_multi]
|
39
|
+
def jsonapi_cache
|
40
|
+
instance_exec(&JSONAPI::Rails.config[:jsonapi_cache])
|
41
|
+
end
|
42
|
+
|
43
|
+
# Hook for default fields.
|
44
|
+
# @return [Hash{Symbol=>Array<Symbol>},nil]
|
45
|
+
def jsonapi_fields
|
46
|
+
instance_exec(&JSONAPI::Rails.config[:jsonapi_fields])
|
47
|
+
end
|
48
|
+
|
49
|
+
# Hook for default includes.
|
50
|
+
# @return [IncludeDirective]
|
51
|
+
def jsonapi_include
|
52
|
+
instance_exec(&JSONAPI::Rails.config[:jsonapi_include])
|
53
|
+
end
|
54
|
+
|
55
|
+
# Hook for default links.
|
56
|
+
# @return [Hash]
|
57
|
+
def jsonapi_links
|
58
|
+
instance_exec(&JSONAPI::Rails.config[:jsonapi_links])
|
59
|
+
end
|
60
|
+
|
61
|
+
# Hook for default meta.
|
62
|
+
# @return [Hash,nil]
|
63
|
+
def jsonapi_meta
|
64
|
+
instance_exec(&JSONAPI::Rails.config[:jsonapi_meta])
|
65
|
+
end
|
66
|
+
|
67
|
+
# Hook for pagination scheme.
|
68
|
+
# @return [Hash]
|
69
|
+
def jsonapi_pagination(resources)
|
70
|
+
instance_exec(resources, &JSONAPI::Rails.config[:jsonapi_pagination])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'jsonapi/deserializable/resource'
|
2
|
+
|
3
|
+
module JSONAPI
|
4
|
+
module Rails
|
5
|
+
# Customized deserializable resource class to match ActiveRecord's API.
|
6
|
+
class DeserializableResource < JSONAPI::Deserializable::Resource
|
7
|
+
id
|
8
|
+
type
|
9
|
+
attributes
|
10
|
+
has_one do |_rel, id, type, key|
|
11
|
+
type = type.to_s.singularize.camelize
|
12
|
+
{ "#{key}_id".to_sym => id, "#{key}_type".to_sym => type }
|
13
|
+
end
|
14
|
+
has_many do |_rel, ids, types, key|
|
15
|
+
key = key.to_s.singularize
|
16
|
+
types = types.map { |t| t.to_s.singularize.camelize }
|
17
|
+
{ "#{key}_ids".to_sym => ids, "#{key}_types".to_sym => types }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
module Rails
|
3
|
+
# @private
|
4
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
5
|
+
def render(event)
|
6
|
+
info do
|
7
|
+
"Completed JSON API rendering (#{event.duration.round(2)}ms)"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse(event)
|
12
|
+
info do
|
13
|
+
"Completed JSON API deserializing of #{event.payload[:key]}" \
|
14
|
+
" (#{event.duration.round(2)})"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def logger
|
19
|
+
JSONAPI::Rails.logger
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
JSONAPI::Rails::LogSubscriber.attach_to :'jsonapi-rails'
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'rails/railtie'
|
2
|
-
require 'action_controller'
|
3
|
-
require 'active_support'
|
4
2
|
|
3
|
+
require 'jsonapi/rails/log_subscriber'
|
5
4
|
require 'jsonapi/rails/renderer'
|
6
5
|
|
7
6
|
module JSONAPI
|
@@ -52,7 +51,7 @@ module JSONAPI
|
|
52
51
|
# Renderer proc is evaluated in the controller context.
|
53
52
|
self.content_type ||= Mime[:jsonapi]
|
54
53
|
|
55
|
-
ActiveSupport::Notifications.instrument('render.jsonapi',
|
54
|
+
ActiveSupport::Notifications.instrument('render.jsonapi-rails',
|
56
55
|
resources: resources,
|
57
56
|
options: options) do
|
58
57
|
renderer.render(resources, options, self).to_json
|
@@ -18,17 +18,24 @@ module JSONAPI
|
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
21
22
|
def default_options(options, controller, resources)
|
22
23
|
options.dup.tap do |opts|
|
23
24
|
opts[:class] ||= controller.jsonapi_class
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
opts[:cache] ||= controller.jsonapi_cache
|
26
|
+
opts[:links] =
|
27
|
+
controller.jsonapi_links
|
28
|
+
.merge!(controller.jsonapi_pagination(resources))
|
29
|
+
.merge!(opts[:links] || {})
|
30
|
+
opts[:expose] = controller.jsonapi_expose.merge!(opts[:expose] || {})
|
31
|
+
opts[:fields] ||= controller.jsonapi_fields
|
32
|
+
opts[:include] ||= controller.jsonapi_include
|
28
33
|
opts[:jsonapi] = opts.delete(:jsonapi_object) ||
|
29
34
|
controller.jsonapi_object
|
35
|
+
opts[:meta] ||= controller.jsonapi_meta
|
30
36
|
end
|
31
37
|
end
|
38
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
32
39
|
end
|
33
40
|
|
34
41
|
# @private
|
@@ -52,6 +59,7 @@ module JSONAPI
|
|
52
59
|
def default_options(options, controller)
|
53
60
|
options.dup.tap do |opts|
|
54
61
|
opts[:class] ||= controller.jsonapi_errors_class
|
62
|
+
opts[:links] = controller.jsonapi_links.merge!(opts[:links] || {})
|
55
63
|
opts[:expose] =
|
56
64
|
controller.jsonapi_expose
|
57
65
|
.merge(opts[:expose] || {})
|
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.
|
4
|
+
version: 0.4.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:
|
11
|
+
date: 2019-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jsonapi-rb
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '3.5'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: with_model
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: simplecov
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -125,6 +139,11 @@ files:
|
|
125
139
|
- lib/jsonapi/rails.rb
|
126
140
|
- lib/jsonapi/rails/configuration.rb
|
127
141
|
- lib/jsonapi/rails/controller.rb
|
142
|
+
- lib/jsonapi/rails/controller/deserialization.rb
|
143
|
+
- lib/jsonapi/rails/controller/hooks.rb
|
144
|
+
- lib/jsonapi/rails/deserializable_resource.rb
|
145
|
+
- lib/jsonapi/rails/log_subscriber.rb
|
146
|
+
- lib/jsonapi/rails/logging.rb
|
128
147
|
- lib/jsonapi/rails/railtie.rb
|
129
148
|
- lib/jsonapi/rails/renderer.rb
|
130
149
|
- lib/jsonapi/rails/serializable_active_model_errors.rb
|
@@ -148,8 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
167
|
- !ruby/object:Gem::Version
|
149
168
|
version: '0'
|
150
169
|
requirements: []
|
151
|
-
|
152
|
-
rubygems_version: 2.6.13
|
170
|
+
rubygems_version: 3.0.2
|
153
171
|
signing_key:
|
154
172
|
specification_version: 4
|
155
173
|
summary: jsonapi-rb integrations for Rails.
|