jsonapi.rb 1.5.7 → 2.0.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/README.md +28 -4
- data/lib/jsonapi/active_model_error_serializer.rb +0 -3
- data/lib/jsonapi/error_serializer.rb +8 -3
- data/lib/jsonapi/filtering.rb +7 -2
- data/lib/jsonapi/pagination.rb +25 -5
- data/lib/jsonapi/rails.rb +38 -13
- data/lib/jsonapi/version.rb +1 -1
- data/spec/deserialization_spec.rb +87 -0
- data/spec/dummy.rb +162 -0
- data/spec/errors_spec.rb +168 -0
- data/spec/fetching_spec.rb +65 -0
- data/spec/filtering_spec.rb +101 -0
- data/spec/pagination_spec.rb +246 -0
- data/spec/spec_helper.rb +87 -0
- metadata +37 -27
- data/.github/ISSUE_TEMPLATE.md +0 -16
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
- data/.github/workflows/ci.yml +0 -36
- data/.gitignore +0 -3
- data/.rspec +0 -3
- data/.rubocop.yml +0 -36
- data/.yardstick.yml +0 -29
- data/Gemfile +0 -6
- data/Rakefile +0 -30
- data/jsonapi.rb.gemspec +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2192bbffc57d4ecbe419a90e25728951db4464c5f299e8866afefe72fa393cad
|
4
|
+
data.tar.gz: f7f83b43169207e7cf6d06e6e99cc8c8f705de09c4c83ff9dba5238540577a9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 577c2b0d1801ef2191c25925e407449ff12ba95d7fc5c8433fcbb2b20e532a1b7a51a884f147c5042c38ec27ca9eed6567bfd746aad4ad8895b7a3f90e9043b1
|
7
|
+
data.tar.gz: f6ca1bc49fd89c1ea942f3c047234d76c4fa1d7604bd06aa5d67c43dad93603cb19e6c542ec13837d1db5e3fbe923ec4799fd865c96c08822dcab7cb160d7f7e
|
data/README.md
CHANGED
@@ -31,7 +31,7 @@ Main goals:
|
|
31
31
|
|
32
32
|
The available features include:
|
33
33
|
|
34
|
-
* object serialization (powered by
|
34
|
+
* object serialization (powered by JSON:API Serializer, was `fast_jsonapi`)
|
35
35
|
* [error handling](https://jsonapi.org/format/#errors) (parameters,
|
36
36
|
validation, generic errors)
|
37
37
|
* fetching of the data (support for
|
@@ -39,16 +39,26 @@ The available features include:
|
|
39
39
|
[sparse fields](https://jsonapi.org/format/#fetching-sparse-fieldsets))
|
40
40
|
* [filtering](https://jsonapi.org/format/#fetching-filtering) and
|
41
41
|
[sorting](https://jsonapi.org/format/#fetching-sorting) of the data
|
42
|
-
(powered by Ransack)
|
42
|
+
(powered by Ransack, soft-dependency)
|
43
43
|
* [pagination](https://jsonapi.org/format/#fetching-pagination) support
|
44
44
|
|
45
45
|
## But how?
|
46
46
|
|
47
|
-
Mainly by leveraging [
|
47
|
+
Mainly by leveraging [JSON:API Serializer](https://github.com/jsonapi-serializer/jsonapi-serializer)
|
48
48
|
and [Ransack](https://github.com/activerecord-hackery/ransack).
|
49
49
|
|
50
50
|
Thanks to everyone who worked on these amazing projects!
|
51
51
|
|
52
|
+
## Sponsors
|
53
|
+
|
54
|
+
I'm grateful for the following companies for supporting this project!
|
55
|
+
|
56
|
+
<p align="center">
|
57
|
+
<a href="https://www.luneteyewear.com"><img src="https://user-images.githubusercontent.com/112147/136836142-2bfba96e-447f-4eb6-b137-2445aee81b37.png"/></a>
|
58
|
+
<a href="https://www.startuplandia.io"><img src="https://user-images.githubusercontent.com/112147/136836147-93f8ab17-2465-4477-a7ab-e38255483c66.png"/></a>
|
59
|
+
</p>
|
60
|
+
|
61
|
+
|
52
62
|
## Installation
|
53
63
|
|
54
64
|
Add this line to your application's Gemfile:
|
@@ -100,7 +110,7 @@ The naming scheme follows the `ModuleName::ClassNameSerializer` for an instance
|
|
100
110
|
of the `ModuleName::ClassName`.
|
101
111
|
|
102
112
|
Please follow the
|
103
|
-
[
|
113
|
+
[JSON:API Serializer guide](https://github.com/jsonapi-serializer/jsonapi-serializer#serializer-definition)
|
104
114
|
on how to define a serializer.
|
105
115
|
|
106
116
|
To provide a different naming scheme implement the `jsonapi_serializer_class`
|
@@ -231,6 +241,8 @@ to filter and sort over a collection of records.
|
|
231
241
|
The support is pretty extended and covers also relationships and composite
|
232
242
|
matchers.
|
233
243
|
|
244
|
+
Please add `ransack` to your `Gemfile` in order to benefit from this functionality!
|
245
|
+
|
234
246
|
Here's an example:
|
235
247
|
|
236
248
|
```ruby
|
@@ -290,6 +302,7 @@ class MyController < ActionController::Base
|
|
290
302
|
render jsonapi: paginated
|
291
303
|
end
|
292
304
|
end
|
305
|
+
|
293
306
|
end
|
294
307
|
```
|
295
308
|
|
@@ -306,6 +319,17 @@ use the `jsonapi_pagination_meta` method:
|
|
306
319
|
end
|
307
320
|
|
308
321
|
```
|
322
|
+
|
323
|
+
If you want to change the default number of items per page or define a custom logic to handle page size, use the
|
324
|
+
`jsonapi_page_size` method:
|
325
|
+
|
326
|
+
```ruby
|
327
|
+
def jsonapi_page_size(pagination_params)
|
328
|
+
per_page = pagination_params[:size].to_f.to_i
|
329
|
+
per_page = 30 if per_page > 30 || per_page < 1
|
330
|
+
per_page
|
331
|
+
end
|
332
|
+
```
|
309
333
|
### Deserialization
|
310
334
|
|
311
335
|
`JSONAPI::Deserialization` provides a helper to transform a `JSONAPI` document
|
@@ -1,11 +1,10 @@
|
|
1
|
-
require '
|
1
|
+
require 'jsonapi/serializer'
|
2
2
|
|
3
3
|
module JSONAPI
|
4
4
|
# A simple error serializer
|
5
5
|
class ErrorSerializer
|
6
|
-
include
|
6
|
+
include JSONAPI::Serializer
|
7
7
|
|
8
|
-
set_id :object_id
|
9
8
|
set_type :error
|
10
9
|
|
11
10
|
# Object/Hash attribute helpers.
|
@@ -15,6 +14,12 @@ module JSONAPI
|
|
15
14
|
end
|
16
15
|
end
|
17
16
|
|
17
|
+
# Overwrite the ID extraction method, to skip validations
|
18
|
+
#
|
19
|
+
# @return [NilClass]
|
20
|
+
def self.id_from_record(_record, _params)
|
21
|
+
end
|
22
|
+
|
18
23
|
# Remap the root key to `errors`
|
19
24
|
#
|
20
25
|
# @return [Hash]
|
data/lib/jsonapi/filtering.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
begin
|
2
|
+
require 'active_record'
|
3
|
+
require 'ransack'
|
4
|
+
require_relative 'patches'
|
5
|
+
rescue LoadError
|
6
|
+
warn('Install `ransack` gem before using `JSONAPI::Filtering`!')
|
7
|
+
end
|
3
8
|
|
4
9
|
# Filtering and sorting support
|
5
10
|
module JSONAPI
|
data/lib/jsonapi/pagination.rb
CHANGED
@@ -43,6 +43,8 @@ module JSONAPI
|
|
43
43
|
original_url = request.base_url + request.path + '?'
|
44
44
|
|
45
45
|
pagination.each do |page_name, number|
|
46
|
+
next if page_name == :records
|
47
|
+
|
46
48
|
original_params[:page][:number] = number
|
47
49
|
links[page_name] = original_url + CGI.unescape(
|
48
50
|
original_params.to_query
|
@@ -63,7 +65,7 @@ module JSONAPI
|
|
63
65
|
numbers = { current: page }
|
64
66
|
|
65
67
|
if resources.respond_to?(:unscope)
|
66
|
-
total = resources.unscope(:limit, :offset, :order).
|
68
|
+
total = resources.unscope(:limit, :offset, :order).size
|
67
69
|
else
|
68
70
|
# Try to fetch the cached size first
|
69
71
|
total = resources.instance_variable_get(:@original_size)
|
@@ -82,6 +84,10 @@ module JSONAPI
|
|
82
84
|
numbers[:last] = last_page
|
83
85
|
end
|
84
86
|
|
87
|
+
if total.present?
|
88
|
+
numbers[:records] = total
|
89
|
+
end
|
90
|
+
|
85
91
|
numbers
|
86
92
|
end
|
87
93
|
|
@@ -89,16 +95,30 @@ module JSONAPI
|
|
89
95
|
#
|
90
96
|
# @return [Array] with the offset, limit and the current page number
|
91
97
|
def jsonapi_pagination_params
|
92
|
-
def_per_page = self.class.const_get(:JSONAPI_PAGE_SIZE).to_i
|
93
|
-
|
94
98
|
pagination = params[:page].try(:slice, :number, :size) || {}
|
95
|
-
per_page = pagination
|
96
|
-
per_page = def_per_page if per_page > def_per_page || per_page < 1
|
99
|
+
per_page = jsonapi_page_size(pagination)
|
97
100
|
num = [1, pagination[:number].to_f.to_i].max
|
98
101
|
|
99
102
|
[(num - 1) * per_page, per_page, num]
|
100
103
|
end
|
101
104
|
|
105
|
+
# Retrieves the default page size
|
106
|
+
#
|
107
|
+
# @param per_page_param [Hash] opts the paginations params
|
108
|
+
# @option opts [String] :number the page number requested
|
109
|
+
# @option opts [String] :size the page size requested
|
110
|
+
#
|
111
|
+
# @return [Integer]
|
112
|
+
def jsonapi_page_size(pagination_params)
|
113
|
+
per_page = pagination_params[:size].to_f.to_i
|
114
|
+
|
115
|
+
return self.class
|
116
|
+
.const_get(:JSONAPI_PAGE_SIZE)
|
117
|
+
.to_i if per_page < 1
|
118
|
+
|
119
|
+
per_page
|
120
|
+
end
|
121
|
+
|
102
122
|
# Fallback to Rack's parsed query string when Rails is not available
|
103
123
|
#
|
104
124
|
# @return [Hash]
|
data/lib/jsonapi/rails.rb
CHANGED
@@ -42,11 +42,12 @@ module JSONAPI
|
|
42
42
|
many = JSONAPI::Rails.is_collection?(resource, options[:is_collection])
|
43
43
|
resource = [resource] unless many
|
44
44
|
|
45
|
-
return JSONAPI::
|
46
|
-
.
|
45
|
+
return JSONAPI::Rails.serializer_to_json(
|
46
|
+
JSONAPI::ErrorSerializer.new(resource, options)
|
47
|
+
) unless resource.is_a?(ActiveModel::Errors)
|
47
48
|
|
48
49
|
errors = []
|
49
|
-
model = resource.instance_variable_get(
|
50
|
+
model = resource.instance_variable_get(:@base)
|
50
51
|
|
51
52
|
if respond_to?(:jsonapi_serializer_class, true)
|
52
53
|
model_serializer = jsonapi_serializer_class(model, false)
|
@@ -54,8 +55,18 @@ module JSONAPI
|
|
54
55
|
model_serializer = JSONAPI::Rails.serializer_class(model, false)
|
55
56
|
end
|
56
57
|
|
57
|
-
details =
|
58
|
-
|
58
|
+
details = {}
|
59
|
+
if ::Rails.gem_version >= Gem::Version.new('6.1')
|
60
|
+
resource.each do |error|
|
61
|
+
attr = error.attribute
|
62
|
+
details[attr] ||= []
|
63
|
+
details[attr] << error.detail.merge(message: error.message)
|
64
|
+
end
|
65
|
+
elsif resource.respond_to?(:details)
|
66
|
+
details = resource.details
|
67
|
+
else
|
68
|
+
details = resource.messages
|
69
|
+
end
|
59
70
|
|
60
71
|
details.each do |error_key, error_hashes|
|
61
72
|
error_hashes.each do |error_hash|
|
@@ -66,9 +77,11 @@ module JSONAPI
|
|
66
77
|
end
|
67
78
|
end
|
68
79
|
|
69
|
-
JSONAPI::
|
70
|
-
|
71
|
-
|
80
|
+
JSONAPI::Rails.serializer_to_json(
|
81
|
+
JSONAPI::ActiveModelErrorSerializer.new(
|
82
|
+
errors, params: { model: model, model_serializer: model_serializer }
|
83
|
+
)
|
84
|
+
)
|
72
85
|
end
|
73
86
|
end
|
74
87
|
|
@@ -100,21 +113,21 @@ module JSONAPI
|
|
100
113
|
serializer_class = JSONAPI::Rails.serializer_class(resource, many)
|
101
114
|
end
|
102
115
|
|
103
|
-
|
116
|
+
JSONAPI::Rails.serializer_to_json(
|
117
|
+
serializer_class.new(resource, options)
|
118
|
+
)
|
104
119
|
end
|
105
120
|
end
|
106
121
|
|
107
122
|
# Checks if an object is a collection
|
108
123
|
#
|
109
|
-
#
|
124
|
+
# Basically forwards it to a [JSONAPI::Serializer] as there's no public API
|
110
125
|
#
|
111
126
|
# @param resource [Object] to check
|
112
127
|
# @param force_is_collection [NilClass] flag to overwrite
|
113
128
|
# @return [TrueClass] upon success
|
114
129
|
def self.is_collection?(resource, force_is_collection = nil)
|
115
|
-
|
116
|
-
|
117
|
-
resource.respond_to?(:size) && !resource.respond_to?(:each_pair)
|
130
|
+
JSONAPI::ErrorSerializer.is_collection?(resource, force_is_collection)
|
118
131
|
end
|
119
132
|
|
120
133
|
# Resolves resource serializer class
|
@@ -126,5 +139,17 @@ module JSONAPI
|
|
126
139
|
|
127
140
|
"#{klass.name}Serializer".constantize
|
128
141
|
end
|
142
|
+
|
143
|
+
# Lazily returns the serializer JSON
|
144
|
+
#
|
145
|
+
# @param serializer [Object] to evaluate
|
146
|
+
# @return [String]
|
147
|
+
def self.serializer_to_json(serializer)
|
148
|
+
if serializer.respond_to?(:serialized_json)
|
149
|
+
serializer.serialized_json
|
150
|
+
else
|
151
|
+
serializer.serializable_hash.to_json
|
152
|
+
end
|
153
|
+
end
|
129
154
|
end
|
130
155
|
end
|
data/lib/jsonapi/version.rb
CHANGED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe JSONAPI::Deserialization do
|
4
|
+
let(:jsonapi_deserialize) { UsersController.new.method(:jsonapi_deserialize) }
|
5
|
+
let(:document) do
|
6
|
+
{
|
7
|
+
data: {
|
8
|
+
id: 1,
|
9
|
+
type: 'note',
|
10
|
+
attributes: {
|
11
|
+
title: 'Title 1',
|
12
|
+
date: '2015-12-20'
|
13
|
+
},
|
14
|
+
relationships: {
|
15
|
+
author: {
|
16
|
+
data: {
|
17
|
+
type: 'user',
|
18
|
+
id: 2
|
19
|
+
}
|
20
|
+
},
|
21
|
+
second_author: {
|
22
|
+
data: nil
|
23
|
+
},
|
24
|
+
notes: {
|
25
|
+
data: [
|
26
|
+
{
|
27
|
+
type: 'note',
|
28
|
+
id: 3
|
29
|
+
},
|
30
|
+
{
|
31
|
+
type: 'note',
|
32
|
+
id: 4
|
33
|
+
}
|
34
|
+
]
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#jsonapi_deserialize' do
|
42
|
+
it do
|
43
|
+
expect(jsonapi_deserialize.call(document)).to eq(
|
44
|
+
'id' => 1,
|
45
|
+
'date' => '2015-12-20',
|
46
|
+
'title' => 'Title 1',
|
47
|
+
'author_id' => 2,
|
48
|
+
'second_author_id' => nil,
|
49
|
+
'note_ids' => [3, 4]
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'with `only`' do
|
54
|
+
it do
|
55
|
+
expect(jsonapi_deserialize.call(document, only: :notes)).to eq(
|
56
|
+
'note_ids' => [3, 4]
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with `except`' do
|
62
|
+
it do
|
63
|
+
expect(
|
64
|
+
jsonapi_deserialize.call(document, except: [:date, :title])
|
65
|
+
).to eq(
|
66
|
+
'id' => 1,
|
67
|
+
'author_id' => 2,
|
68
|
+
'second_author_id' => nil,
|
69
|
+
'note_ids' => [3, 4]
|
70
|
+
)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'with `polymorphic`' do
|
75
|
+
it do
|
76
|
+
expect(
|
77
|
+
jsonapi_deserialize.call(
|
78
|
+
document, only: :author, polymorphic: :author
|
79
|
+
)
|
80
|
+
).to eq(
|
81
|
+
'author_id' => 2,
|
82
|
+
'author_type' => User.name
|
83
|
+
)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/spec/dummy.rb
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'rails/all'
|
3
|
+
require 'ransack'
|
4
|
+
require 'jsonapi'
|
5
|
+
|
6
|
+
Rails.logger = Logger.new(STDOUT)
|
7
|
+
Rails.logger.level = ENV['LOG_LEVEL'] || Logger::WARN
|
8
|
+
|
9
|
+
JSONAPI::Rails.install!
|
10
|
+
|
11
|
+
ActiveRecord::Base.logger = Rails.logger
|
12
|
+
ActiveRecord::Base.establish_connection(
|
13
|
+
ENV['DATABASE_URL'] || 'sqlite3::memory:'
|
14
|
+
)
|
15
|
+
|
16
|
+
ActiveRecord::Schema.define do
|
17
|
+
create_table :users, force: true do |t|
|
18
|
+
t.string :first_name
|
19
|
+
t.string :last_name
|
20
|
+
t.timestamps
|
21
|
+
end
|
22
|
+
|
23
|
+
create_table :notes, force: true do |t|
|
24
|
+
t.string :title
|
25
|
+
t.integer :user_id
|
26
|
+
t.integer :quantity
|
27
|
+
t.timestamps
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class User < ActiveRecord::Base
|
32
|
+
has_many :notes
|
33
|
+
end
|
34
|
+
|
35
|
+
class Note < ActiveRecord::Base
|
36
|
+
validates_format_of :title, without: /BAD_TITLE/
|
37
|
+
validates_numericality_of :quantity, less_than: 100, if: :quantity?
|
38
|
+
belongs_to :user, required: true
|
39
|
+
end
|
40
|
+
|
41
|
+
class CustomNoteSerializer
|
42
|
+
include JSONAPI::Serializer
|
43
|
+
|
44
|
+
set_type :note
|
45
|
+
belongs_to :user
|
46
|
+
attributes(:title, :quantity, :created_at, :updated_at)
|
47
|
+
end
|
48
|
+
|
49
|
+
class UserSerializer
|
50
|
+
include JSONAPI::Serializer
|
51
|
+
|
52
|
+
has_many :notes, serializer: CustomNoteSerializer
|
53
|
+
attributes(:last_name, :created_at, :updated_at)
|
54
|
+
|
55
|
+
attribute :first_name do |object, params|
|
56
|
+
if params[:first_name_upcase]
|
57
|
+
object.first_name.upcase
|
58
|
+
else
|
59
|
+
object.first_name
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class Dummy < Rails::Application
|
65
|
+
secrets.secret_key_base = '_'
|
66
|
+
config.hosts << 'www.example.com' if config.respond_to?(:hosts)
|
67
|
+
|
68
|
+
routes.draw do
|
69
|
+
scope defaults: { format: :jsonapi } do
|
70
|
+
resources :users, only: [:index]
|
71
|
+
resources :notes, only: [:update]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class UsersController < ActionController::Base
|
77
|
+
include JSONAPI::Fetching
|
78
|
+
include JSONAPI::Filtering
|
79
|
+
include JSONAPI::Pagination
|
80
|
+
include JSONAPI::Deserialization
|
81
|
+
|
82
|
+
def index
|
83
|
+
allowed_fields = [
|
84
|
+
:first_name, :last_name, :created_at,
|
85
|
+
:notes_created_at, :notes_quantity
|
86
|
+
]
|
87
|
+
options = { sort_with_expressions: true }
|
88
|
+
|
89
|
+
jsonapi_filter(User.all, allowed_fields, options) do |filtered|
|
90
|
+
result = filtered.result
|
91
|
+
|
92
|
+
if params[:sort].to_s.include?('notes_quantity')
|
93
|
+
render jsonapi: result.group('id').to_a
|
94
|
+
return
|
95
|
+
end
|
96
|
+
|
97
|
+
result = result.to_a if params[:as_list]
|
98
|
+
|
99
|
+
jsonapi_paginate(result) do |paginated|
|
100
|
+
render jsonapi: paginated
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
def jsonapi_meta(resources)
|
107
|
+
{
|
108
|
+
many: true,
|
109
|
+
pagination: jsonapi_pagination_meta(resources)
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
def jsonapi_serializer_params
|
114
|
+
{
|
115
|
+
first_name_upcase: params[:upcase]
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class NotesController < ActionController::Base
|
121
|
+
include JSONAPI::Errors
|
122
|
+
include JSONAPI::Deserialization
|
123
|
+
|
124
|
+
def update
|
125
|
+
raise_error! if params[:id] == 'tada'
|
126
|
+
|
127
|
+
note = Note.find(params[:id])
|
128
|
+
|
129
|
+
if note.update(note_params)
|
130
|
+
render jsonapi: note
|
131
|
+
else
|
132
|
+
note.errors.add(:title, message: 'has typos') if note.errors.key?(:title)
|
133
|
+
|
134
|
+
render jsonapi_errors: note.errors, status: :unprocessable_entity
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
def render_jsonapi_internal_server_error(exception)
|
140
|
+
Rails.logger.error(exception)
|
141
|
+
super(exception)
|
142
|
+
end
|
143
|
+
|
144
|
+
def jsonapi_serializer_class(resource, is_collection)
|
145
|
+
JSONAPI::Rails.serializer_class(resource, is_collection)
|
146
|
+
rescue NameError
|
147
|
+
klass = resource.class
|
148
|
+
klass = resource.first.class if is_collection
|
149
|
+
"Custom#{klass.name}Serializer".constantize
|
150
|
+
end
|
151
|
+
|
152
|
+
def note_params
|
153
|
+
# Will trigger required attribute error handling
|
154
|
+
params.require(:data).require(:attributes).require(:title)
|
155
|
+
|
156
|
+
jsonapi_deserialize(params)
|
157
|
+
end
|
158
|
+
|
159
|
+
def jsonapi_meta(resources)
|
160
|
+
{ single: true }
|
161
|
+
end
|
162
|
+
end
|