jsonapi-rails 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|