jsonapi_actions 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd75b7ea62934cf27cc351d4327cf302af2ab1f5aed66d6d6075575e974d90b6
4
- data.tar.gz: 56008596f5f59e8eb0640b2d0be4b81eed49dd6fdc7e0f08af5d9f10fc683687
3
+ metadata.gz: fe65b6ed02022e7f5962df4faca6f9326aa69e270ce3a7206d23b604141b03d8
4
+ data.tar.gz: f429a5e20e6caa7f485b25873d30887bde4321e12ff22483505ffce2ded6b249
5
5
  SHA512:
6
- metadata.gz: 709f2ae770a5efbfca5252997c866205a898eb85cc77dddc5517a936d99910e169f7767ecd1a677ec33b4aef30157236528260e9d629cb937578250fb489350b
7
- data.tar.gz: 47e353f3fa687d0ee7a8463dfa412b110982bfcf10c2f294084603bce6f12d29ae937befb795549be5b3bc36f59ce2c9a2f85c4368a2c0a217a57c79159f93c5
6
+ metadata.gz: 68cf00f70d0727172195ddc306e5b450e83cf003203c94cdbfa85677e4c9fde9dc3853737e17640d6b9546f47287481b240653c03c13bfb72356d5f820ab6770
7
+ data.tar.gz: '0992c33f6b4e04eb049ffef3139dba7b7339ace3ebff6d66a631ab408d52395ca038a4ec47c23b263bde7a83b09b78715659747d00c7edfcf90e3021ace19da6'
data/.gitignore CHANGED
@@ -10,3 +10,4 @@
10
10
 
11
11
  # rspec failure tracking
12
12
  .rspec_status
13
+ .ruby-*
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.5.3
1
+ ruby-2.7.4
data/CHANGELOG.md CHANGED
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.5.0] - 2023-02-22
8
+ ### Added
9
+ - Added `serializer_params` method to more easily allow for custom serializer params.
10
+
7
11
  ## [0.2.2] - 2020-05-18
8
12
  ### Fixed
9
13
  - JsonapiActions#json_response uses `defined?` to check for serializer library
data/Gemfile.lock CHANGED
@@ -1,133 +1,151 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jsonapi_actions (0.1.2)
4
+ jsonapi_actions (0.4.0)
5
5
  kaminari (>= 1.0, < 2.0)
6
- rails (>= 4.0, < 7.0)
6
+ rails (>= 4.0, < 7.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- actioncable (6.0.2.2)
12
- actionpack (= 6.0.2.2)
11
+ actioncable (7.0.4)
12
+ actionpack (= 7.0.4)
13
+ activesupport (= 7.0.4)
13
14
  nio4r (~> 2.0)
14
15
  websocket-driver (>= 0.6.1)
15
- actionmailbox (6.0.2.2)
16
- actionpack (= 6.0.2.2)
17
- activejob (= 6.0.2.2)
18
- activerecord (= 6.0.2.2)
19
- activestorage (= 6.0.2.2)
20
- activesupport (= 6.0.2.2)
16
+ actionmailbox (7.0.4)
17
+ actionpack (= 7.0.4)
18
+ activejob (= 7.0.4)
19
+ activerecord (= 7.0.4)
20
+ activestorage (= 7.0.4)
21
+ activesupport (= 7.0.4)
21
22
  mail (>= 2.7.1)
22
- actionmailer (6.0.2.2)
23
- actionpack (= 6.0.2.2)
24
- actionview (= 6.0.2.2)
25
- activejob (= 6.0.2.2)
23
+ net-imap
24
+ net-pop
25
+ net-smtp
26
+ actionmailer (7.0.4)
27
+ actionpack (= 7.0.4)
28
+ actionview (= 7.0.4)
29
+ activejob (= 7.0.4)
30
+ activesupport (= 7.0.4)
26
31
  mail (~> 2.5, >= 2.5.4)
32
+ net-imap
33
+ net-pop
34
+ net-smtp
27
35
  rails-dom-testing (~> 2.0)
28
- actionpack (6.0.2.2)
29
- actionview (= 6.0.2.2)
30
- activesupport (= 6.0.2.2)
31
- rack (~> 2.0, >= 2.0.8)
36
+ actionpack (7.0.4)
37
+ actionview (= 7.0.4)
38
+ activesupport (= 7.0.4)
39
+ rack (~> 2.0, >= 2.2.0)
32
40
  rack-test (>= 0.6.3)
33
41
  rails-dom-testing (~> 2.0)
34
42
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
35
- actiontext (6.0.2.2)
36
- actionpack (= 6.0.2.2)
37
- activerecord (= 6.0.2.2)
38
- activestorage (= 6.0.2.2)
39
- activesupport (= 6.0.2.2)
43
+ actiontext (7.0.4)
44
+ actionpack (= 7.0.4)
45
+ activerecord (= 7.0.4)
46
+ activestorage (= 7.0.4)
47
+ activesupport (= 7.0.4)
48
+ globalid (>= 0.6.0)
40
49
  nokogiri (>= 1.8.5)
41
- actionview (6.0.2.2)
42
- activesupport (= 6.0.2.2)
50
+ actionview (7.0.4)
51
+ activesupport (= 7.0.4)
43
52
  builder (~> 3.1)
44
53
  erubi (~> 1.4)
45
54
  rails-dom-testing (~> 2.0)
46
55
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
47
- activejob (6.0.2.2)
48
- activesupport (= 6.0.2.2)
56
+ activejob (7.0.4)
57
+ activesupport (= 7.0.4)
49
58
  globalid (>= 0.3.6)
50
- activemodel (6.0.2.2)
51
- activesupport (= 6.0.2.2)
52
- activerecord (6.0.2.2)
53
- activemodel (= 6.0.2.2)
54
- activesupport (= 6.0.2.2)
55
- activestorage (6.0.2.2)
56
- actionpack (= 6.0.2.2)
57
- activejob (= 6.0.2.2)
58
- activerecord (= 6.0.2.2)
59
- marcel (~> 0.3.1)
60
- activesupport (6.0.2.2)
59
+ activemodel (7.0.4)
60
+ activesupport (= 7.0.4)
61
+ activerecord (7.0.4)
62
+ activemodel (= 7.0.4)
63
+ activesupport (= 7.0.4)
64
+ activestorage (7.0.4)
65
+ actionpack (= 7.0.4)
66
+ activejob (= 7.0.4)
67
+ activerecord (= 7.0.4)
68
+ activesupport (= 7.0.4)
69
+ marcel (~> 1.0)
70
+ mini_mime (>= 1.1.0)
71
+ activesupport (7.0.4)
61
72
  concurrent-ruby (~> 1.0, >= 1.0.2)
62
- i18n (>= 0.7, < 2)
63
- minitest (~> 5.1)
64
- tzinfo (~> 1.1)
65
- zeitwerk (~> 2.2)
73
+ i18n (>= 1.6, < 2)
74
+ minitest (>= 5.1)
75
+ tzinfo (~> 2.0)
66
76
  builder (3.2.4)
67
- concurrent-ruby (1.1.6)
77
+ concurrent-ruby (1.1.10)
68
78
  crass (1.0.6)
69
79
  diff-lcs (1.3)
70
- erubi (1.9.0)
71
- globalid (0.4.2)
72
- activesupport (>= 4.2.0)
73
- i18n (1.8.2)
80
+ erubi (1.11.0)
81
+ globalid (1.0.0)
82
+ activesupport (>= 5.0)
83
+ i18n (1.12.0)
74
84
  concurrent-ruby (~> 1.0)
75
- kaminari (1.2.0)
85
+ kaminari (1.2.2)
76
86
  activesupport (>= 4.1.0)
77
- kaminari-actionview (= 1.2.0)
78
- kaminari-activerecord (= 1.2.0)
79
- kaminari-core (= 1.2.0)
80
- kaminari-actionview (1.2.0)
87
+ kaminari-actionview (= 1.2.2)
88
+ kaminari-activerecord (= 1.2.2)
89
+ kaminari-core (= 1.2.2)
90
+ kaminari-actionview (1.2.2)
81
91
  actionview
82
- kaminari-core (= 1.2.0)
83
- kaminari-activerecord (1.2.0)
92
+ kaminari-core (= 1.2.2)
93
+ kaminari-activerecord (1.2.2)
84
94
  activerecord
85
- kaminari-core (= 1.2.0)
86
- kaminari-core (1.2.0)
87
- loofah (2.4.0)
95
+ kaminari-core (= 1.2.2)
96
+ kaminari-core (1.2.2)
97
+ loofah (2.19.0)
88
98
  crass (~> 1.0.2)
89
99
  nokogiri (>= 1.5.9)
90
100
  mail (2.7.1)
91
101
  mini_mime (>= 0.1.1)
92
- marcel (0.3.3)
93
- mimemagic (~> 0.3.2)
102
+ marcel (1.0.2)
94
103
  method_source (1.0.0)
95
- mimemagic (0.3.4)
96
- mini_mime (1.0.2)
97
- mini_portile2 (2.4.0)
98
- minitest (5.14.0)
99
- nio4r (2.5.2)
100
- nokogiri (1.10.9)
101
- mini_portile2 (~> 2.4.0)
102
- rack (2.2.2)
103
- rack-test (1.1.0)
104
- rack (>= 1.0, < 3)
105
- rails (6.0.2.2)
106
- actioncable (= 6.0.2.2)
107
- actionmailbox (= 6.0.2.2)
108
- actionmailer (= 6.0.2.2)
109
- actionpack (= 6.0.2.2)
110
- actiontext (= 6.0.2.2)
111
- actionview (= 6.0.2.2)
112
- activejob (= 6.0.2.2)
113
- activemodel (= 6.0.2.2)
114
- activerecord (= 6.0.2.2)
115
- activestorage (= 6.0.2.2)
116
- activesupport (= 6.0.2.2)
117
- bundler (>= 1.3.0)
118
- railties (= 6.0.2.2)
119
- sprockets-rails (>= 2.0.0)
104
+ mini_mime (1.1.2)
105
+ minitest (5.16.3)
106
+ net-imap (0.3.1)
107
+ net-protocol
108
+ net-pop (0.1.2)
109
+ net-protocol
110
+ net-protocol (0.1.3)
111
+ timeout
112
+ net-smtp (0.3.3)
113
+ net-protocol
114
+ nio4r (2.5.8)
115
+ nokogiri (1.13.9-arm64-darwin)
116
+ racc (~> 1.4)
117
+ nokogiri (1.13.9-x86_64-darwin)
118
+ racc (~> 1.4)
119
+ racc (1.6.0)
120
+ rack (2.2.4)
121
+ rack-test (2.0.2)
122
+ rack (>= 1.3)
123
+ rails (7.0.4)
124
+ actioncable (= 7.0.4)
125
+ actionmailbox (= 7.0.4)
126
+ actionmailer (= 7.0.4)
127
+ actionpack (= 7.0.4)
128
+ actiontext (= 7.0.4)
129
+ actionview (= 7.0.4)
130
+ activejob (= 7.0.4)
131
+ activemodel (= 7.0.4)
132
+ activerecord (= 7.0.4)
133
+ activestorage (= 7.0.4)
134
+ activesupport (= 7.0.4)
135
+ bundler (>= 1.15.0)
136
+ railties (= 7.0.4)
120
137
  rails-dom-testing (2.0.3)
121
138
  activesupport (>= 4.2.0)
122
139
  nokogiri (>= 1.6)
123
- rails-html-sanitizer (1.3.0)
140
+ rails-html-sanitizer (1.4.3)
124
141
  loofah (~> 2.3)
125
- railties (6.0.2.2)
126
- actionpack (= 6.0.2.2)
127
- activesupport (= 6.0.2.2)
142
+ railties (7.0.4)
143
+ actionpack (= 7.0.4)
144
+ activesupport (= 7.0.4)
128
145
  method_source
129
- rake (>= 0.8.7)
130
- thor (>= 0.20.3, < 2.0)
146
+ rake (>= 12.2)
147
+ thor (~> 1.0)
148
+ zeitwerk (~> 2.5)
131
149
  rake (13.0.1)
132
150
  rspec (3.8.0)
133
151
  rspec-core (~> 3.8.0)
@@ -142,24 +160,19 @@ GEM
142
160
  diff-lcs (>= 1.2.0, < 2.0)
143
161
  rspec-support (~> 3.8.0)
144
162
  rspec-support (3.8.0)
145
- sprockets (4.0.0)
163
+ thor (1.2.1)
164
+ timeout (0.3.0)
165
+ tzinfo (2.0.5)
146
166
  concurrent-ruby (~> 1.0)
147
- rack (> 1, < 3)
148
- sprockets-rails (3.2.1)
149
- actionpack (>= 4.0)
150
- activesupport (>= 4.0)
151
- sprockets (>= 3.0.0)
152
- thor (1.0.1)
153
- thread_safe (0.3.6)
154
- tzinfo (1.2.6)
155
- thread_safe (~> 0.1)
156
- websocket-driver (0.7.1)
167
+ websocket-driver (0.7.5)
157
168
  websocket-extensions (>= 0.1.0)
158
- websocket-extensions (0.1.4)
159
- zeitwerk (2.3.0)
169
+ websocket-extensions (0.1.5)
170
+ zeitwerk (2.6.6)
160
171
 
161
172
  PLATFORMS
173
+ arm64-darwin-22
162
174
  ruby
175
+ x86_64-darwin-20
163
176
 
164
177
  DEPENDENCIES
165
178
  bundler (~> 2.0)
@@ -168,4 +181,4 @@ DEPENDENCIES
168
181
  rspec (~> 3.0)
169
182
 
170
183
  BUNDLED WITH
171
- 2.0.1
184
+ 2.2.2
@@ -27,6 +27,6 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "rake", "~> 13.0"
28
28
  spec.add_development_dependency "rspec", "~> 3.0"
29
29
 
30
- spec.add_dependency 'rails', '>= 4.0', '< 7.0'
30
+ spec.add_dependency 'rails', '>= 4.0', '< 7.1'
31
31
  spec.add_dependency 'kaminari', '>= 1.0', '< 2.0'
32
32
  end
@@ -1,3 +1,3 @@
1
1
  module JsonapiActions
2
- VERSION = "0.3.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -74,146 +74,148 @@ module JsonapiActions
74
74
 
75
75
  private
76
76
 
77
- def metadata
78
- {}
79
- end
77
+ def metadata
78
+ {}
79
+ end
80
80
 
81
- def parent_scope(records)
82
- return records if self.class.parent_associations.blank?
81
+ def parent_scope(records)
82
+ return records if self.class.parent_associations.blank?
83
83
 
84
- self.class.parent_associations.each do |parent|
85
- next if params[parent[:param]].blank?
84
+ self.class.parent_associations.each do |parent|
85
+ next if params[parent[:param]].blank?
86
86
 
87
- records = records.joins(parent[:association]) unless parent[:association].blank?
88
- records = if parent[:table]
89
- records.where(parent[:table] => { parent[:attribute] => params[parent[:param]] })
90
- else
91
- records.where(parent[:attribute] => params[parent[:param]])
92
- end
93
- end
87
+ records = records.joins(parent[:association]) unless parent[:association].blank?
88
+ records = if parent[:table]
89
+ records.where(parent[:table] => { parent[:attribute] => params[parent[:param]] })
90
+ else
91
+ records.where(parent[:attribute] => params[parent[:param]])
92
+ end
93
+ end
94
94
 
95
- records
96
- end
95
+ records
96
+ end
97
97
 
98
- def filter(records)
99
- records
100
- end
98
+ def filter(records)
99
+ records
100
+ end
101
101
 
102
- def sort(records)
103
- return records if params[:sort].blank?
104
- order = {}
102
+ def sort(records)
103
+ return records if params[:sort].blank?
104
+ order = {}
105
105
 
106
- params[:sort].split(',').each do |sort|
107
- if sort[0] == '-'
108
- order[sort[1..-1]] = :desc
109
- else
110
- order[sort] = :asc
106
+ params[:sort].split(',').each do |sort|
107
+ if sort[0] == '-'
108
+ order[sort[1..-1]] = :desc
109
+ else
110
+ order[sort] = :asc
111
+ end
111
112
  end
113
+
114
+ return records.order(order)
112
115
  end
113
116
 
114
- return records.order(order)
115
- end
117
+ def paginate(records)
118
+ records.page(page[:number]).per(page[:size])
119
+ end
116
120
 
117
- def paginate(records)
118
- records.page(page[:number]).per(page[:size])
119
- end
121
+ def page
122
+ @page ||= begin
123
+ page = {}
124
+ page[:number] = (params.dig(:page, :number) || 1).to_i
125
+ page[:size] = [[(params.dig(:page, :size) || 20).to_i, 1000].min, 1].max
126
+ page
127
+ end
128
+ end
120
129
 
121
- def page
122
- @page ||= begin
123
- page = {}
124
- page[:number] = (params.dig(:page, :number) || 1).to_i
125
- page[:size] = [[(params.dig(:page, :size) || 20).to_i, 1000].min, 1].max
126
- page
127
- end
128
- end
130
+ def set_record
131
+ @record = model.find(params[:id])
132
+ authorize(@record)
133
+ end
129
134
 
130
- def set_record
131
- @record = model.find(params[:id])
132
- authorize(@record)
133
- end
135
+ def id_param
136
+ params.require(:data).permit(policy(@record).permitted_attributes)[:id]
137
+ end
134
138
 
135
- def id_param
136
- params.require(:data).permit(policy(@record).permitted_attributes)[:id]
137
- end
139
+ def record_params
140
+ params.require(:data).require(:attributes).permit(policy(@record).permitted_attributes)
141
+ end
138
142
 
139
- def record_params
140
- params.require(:data).require(:attributes).permit(policy(@record).permitted_attributes)
141
- end
143
+ def include_param
144
+ if %w[* **].include? params[:include]
145
+ inclusion_map
146
+ else
147
+ params[:include].to_s.split(',').reject(&:blank?).map(&:to_sym)
148
+ end
149
+ end
142
150
 
143
- def include_param
144
- if %w[* **].include? params[:include]
145
- inclusion_map
146
- else
147
- params[:include].to_s.split(',').reject(&:blank?).map(&:to_sym)
151
+ def inclusion_map
152
+ InclusionMapper.new(serializer, include: params[:include]).map
148
153
  end
149
- end
150
154
 
151
- def inclusion_map
152
- InclusionMapper.new(serializer, include: params[:include]).map
153
- end
155
+ def unprocessable_entity(record)
156
+ Rails.logger.debug(record.errors.messages)
157
+ { json: record.errors.messages, status: :unprocessable_entity }
158
+ end
154
159
 
155
- def unprocessable_entity(record)
156
- Rails.logger.debug(record.errors.messages)
157
- { json: record.errors.messages, status: :unprocessable_entity }
158
- end
160
+ def pagination_meta(collection)
161
+ return {} if collection.nil?
159
162
 
160
- def pagination_meta(collection)
161
- return {} if collection.nil?
163
+ {
164
+ current_page: collection.current_page,
165
+ next_page: collection.next_page,
166
+ prev_page: collection.prev_page,
167
+ total_pages: collection.total_pages,
168
+ total_count: collection.total_count
169
+ }
170
+ end
162
171
 
163
- {
164
- current_page: collection.current_page,
165
- next_page: collection.next_page,
166
- prev_page: collection.prev_page,
167
- total_pages: collection.total_pages,
168
- total_count: collection.total_count
169
- }
170
- end
172
+ def model
173
+ self.class.model || self.class.model_name.constantize
174
+ end
171
175
 
172
- def model
173
- self.class.model || self.class.model_name.constantize
174
- end
176
+ def json_response(data, options = {})
177
+ if defined?(JSONAPI::Serializer) || defined?(FastJsonapi)
178
+ {
179
+ json: serializer(data).new(data, options.deep_merge(
180
+ include: include_param,
181
+ meta: metadata,
182
+ params: serializer_params)
183
+ )
184
+ }
175
185
 
176
- def json_response(data, options = {})
177
- if defined?(JSONAPI::Serializer) || defined?(FastJsonapi)
178
- {
179
- json: serializer(data).new(data, options.deep_merge(
180
- include: include_param,
181
- meta: metadata,
182
- params: {
183
- current_user: try(:current_user)
184
- })
185
- )
186
- }
186
+ elsif defined?(ActiveModel::Serializer)
187
+ { json: data }.merge(meta: metadata, include: include_param).merge(options)
187
188
 
188
- elsif defined?(ActiveModel::Serializer)
189
- { json: data }.merge(meta: metadata, include: include_param).merge(options)
189
+ else
190
+ { json: { data: data }.merge(options) }
191
+ end
192
+ end
190
193
 
191
- else
192
- { json: { data: data }.merge(options) }
194
+ def serializer(data = nil)
195
+ serializer_classes = [
196
+ self.class.serializer,
197
+ data.try(:serializer_class),
198
+ "#{data.class.name}Serializer".safe_constantize,
199
+ data.try(:first).try(:serializer_class),
200
+ "#{data.try(:first).class.name}Serializer".safe_constantize
201
+ ].compact
202
+
203
+ if serializer_classes.any?
204
+ serializer_classes.first
205
+ else
206
+ "#{model.name}Serializer".safe_constantize
207
+ end
208
+ rescue NoMethodError, NameError
209
+ raise 'Unknown serializer'
193
210
  end
194
- end
195
211
 
196
- def serializer(data = nil)
197
- serializer_classes = [
198
- self.class.serializer,
199
- data.try(:serializer_class),
200
- "#{data.class.name}Serializer".safe_constantize,
201
- data.try(:first).try(:serializer_class),
202
- "#{data.try(:first).class.name}Serializer".safe_constantize
203
- ].compact
204
-
205
- if serializer_classes.any?
206
- serializer_classes.first
207
- else
208
- "#{model.name}Serializer".safe_constantize
212
+ def serializer_params
213
+ { current_user: try(:current_user) }
209
214
  end
210
- rescue NoMethodError, NameError
211
- raise 'Unknown serializer'
212
- end
213
215
 
214
- def eager_load(records)
215
- records
216
- end
216
+ def eager_load(records)
217
+ records
218
+ end
217
219
  end
218
220
 
219
221
  module ClassMethods
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi_actions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Pheasey
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-22 00:00:00.000000000 Z
11
+ date: 2023-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -61,7 +61,7 @@ dependencies:
61
61
  version: '4.0'
62
62
  - - "<"
63
63
  - !ruby/object:Gem::Version
64
- version: '7.0'
64
+ version: '7.1'
65
65
  type: :runtime
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
@@ -71,7 +71,7 @@ dependencies:
71
71
  version: '4.0'
72
72
  - - "<"
73
73
  - !ruby/object:Gem::Version
74
- version: '7.0'
74
+ version: '7.1'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: kaminari
77
77
  requirement: !ruby/object:Gem::Requirement
@@ -139,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
139
  - !ruby/object:Gem::Version
140
140
  version: '0'
141
141
  requirements: []
142
- rubygems_version: 3.0.8
142
+ rubygems_version: 3.1.6
143
143
  signing_key:
144
144
  specification_version: 4
145
145
  summary: Rails JSON:API Controller Actions