jsonapi-resources 0.7.1.beta1 → 0.7.1.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +248 -74
  3. data/lib/jsonapi-resources.rb +5 -3
  4. data/lib/jsonapi/acts_as_resource_controller.rb +77 -14
  5. data/lib/jsonapi/configuration.rb +77 -16
  6. data/lib/jsonapi/error.rb +12 -0
  7. data/lib/jsonapi/error_codes.rb +2 -0
  8. data/lib/jsonapi/exceptions.rb +29 -9
  9. data/lib/jsonapi/formatter.rb +29 -4
  10. data/lib/jsonapi/link_builder.rb +18 -18
  11. data/lib/jsonapi/mime_types.rb +25 -6
  12. data/lib/jsonapi/naive_cache.rb +30 -0
  13. data/lib/jsonapi/operation.rb +10 -342
  14. data/lib/jsonapi/operation_dispatcher.rb +87 -0
  15. data/lib/jsonapi/operation_result.rb +2 -1
  16. data/lib/jsonapi/paginator.rb +6 -2
  17. data/lib/jsonapi/processor.rb +283 -0
  18. data/lib/jsonapi/relationship.rb +6 -4
  19. data/lib/jsonapi/{request.rb → request_parser.rb} +46 -35
  20. data/lib/jsonapi/resource.rb +88 -13
  21. data/lib/jsonapi/resource_controller.rb +2 -14
  22. data/lib/jsonapi/resource_controller_metal.rb +17 -0
  23. data/lib/jsonapi/resource_serializer.rb +62 -47
  24. data/lib/jsonapi/resources/version.rb +1 -1
  25. data/lib/jsonapi/response_document.rb +13 -2
  26. data/lib/jsonapi/routing_ext.rb +49 -11
  27. metadata +37 -129
  28. data/.gitignore +0 -22
  29. data/.travis.yml +0 -9
  30. data/Gemfile +0 -23
  31. data/Rakefile +0 -20
  32. data/jsonapi-resources.gemspec +0 -29
  33. data/lib/jsonapi/active_record_operations_processor.rb +0 -35
  34. data/lib/jsonapi/operations_processor.rb +0 -120
  35. data/locales/en.yml +0 -80
  36. data/test/config/database.yml +0 -5
  37. data/test/controllers/controller_test.rb +0 -3312
  38. data/test/fixtures/active_record.rb +0 -1486
  39. data/test/fixtures/author_details.yml +0 -9
  40. data/test/fixtures/book_authors.yml +0 -3
  41. data/test/fixtures/book_comments.yml +0 -12
  42. data/test/fixtures/books.yml +0 -7
  43. data/test/fixtures/categories.yml +0 -35
  44. data/test/fixtures/comments.yml +0 -21
  45. data/test/fixtures/comments_tags.yml +0 -20
  46. data/test/fixtures/companies.yml +0 -4
  47. data/test/fixtures/craters.yml +0 -9
  48. data/test/fixtures/customers.yml +0 -11
  49. data/test/fixtures/documents.yml +0 -3
  50. data/test/fixtures/expense_entries.yml +0 -13
  51. data/test/fixtures/facts.yml +0 -11
  52. data/test/fixtures/hair_cuts.yml +0 -3
  53. data/test/fixtures/iso_currencies.yml +0 -17
  54. data/test/fixtures/line_items.yml +0 -37
  55. data/test/fixtures/makes.yml +0 -2
  56. data/test/fixtures/moons.yml +0 -6
  57. data/test/fixtures/numeros_telefone.yml +0 -3
  58. data/test/fixtures/order_flags.yml +0 -7
  59. data/test/fixtures/people.yml +0 -31
  60. data/test/fixtures/pictures.yml +0 -15
  61. data/test/fixtures/planet_types.yml +0 -19
  62. data/test/fixtures/planets.yml +0 -47
  63. data/test/fixtures/posts.yml +0 -102
  64. data/test/fixtures/posts_tags.yml +0 -59
  65. data/test/fixtures/preferences.yml +0 -14
  66. data/test/fixtures/products.yml +0 -3
  67. data/test/fixtures/purchase_orders.yml +0 -23
  68. data/test/fixtures/sections.yml +0 -8
  69. data/test/fixtures/tags.yml +0 -39
  70. data/test/fixtures/vehicles.yml +0 -17
  71. data/test/fixtures/web_pages.yml +0 -3
  72. data/test/helpers/assertions.rb +0 -13
  73. data/test/helpers/functional_helpers.rb +0 -59
  74. data/test/helpers/value_matchers.rb +0 -60
  75. data/test/helpers/value_matchers_test.rb +0 -40
  76. data/test/integration/requests/namespaced_model_test.rb +0 -13
  77. data/test/integration/requests/request_test.rb +0 -932
  78. data/test/integration/routes/routes_test.rb +0 -218
  79. data/test/integration/sti_fields_test.rb +0 -18
  80. data/test/lib/generators/jsonapi/controller_generator_test.rb +0 -25
  81. data/test/lib/generators/jsonapi/resource_generator_test.rb +0 -30
  82. data/test/test_helper.rb +0 -342
  83. data/test/unit/formatters/dasherized_key_formatter_test.rb +0 -8
  84. data/test/unit/jsonapi_request/jsonapi_request_test.rb +0 -199
  85. data/test/unit/operation/operations_processor_test.rb +0 -528
  86. data/test/unit/pagination/offset_paginator_test.rb +0 -245
  87. data/test/unit/pagination/paged_paginator_test.rb +0 -242
  88. data/test/unit/resource/resource_test.rb +0 -560
  89. data/test/unit/serializer/include_directives_test.rb +0 -113
  90. data/test/unit/serializer/link_builder_test.rb +0 -244
  91. data/test/unit/serializer/polymorphic_serializer_test.rb +0 -383
  92. data/test/unit/serializer/response_document_test.rb +0 -61
  93. data/test/unit/serializer/serializer_test.rb +0 -1939
@@ -1,560 +0,0 @@
1
- require File.expand_path('../../../test_helper', __FILE__)
2
-
3
- class ArticleResource < JSONAPI::Resource
4
- model_name 'Post'
5
-
6
- def self.records(options)
7
- options[:context].posts
8
- end
9
- end
10
-
11
- class PostWithBadAfterSave < ActiveRecord::Base
12
- self.table_name = 'posts'
13
- after_save :do_some_after_save_stuff
14
-
15
- def do_some_after_save_stuff
16
- errors[:base] << 'Boom! Error added in after_save callback.'
17
- raise ActiveRecord::RecordInvalid.new(self)
18
- end
19
- end
20
-
21
- class ArticleWithBadAfterSaveResource < JSONAPI::Resource
22
- model_name 'PostWithBadAfterSave'
23
- attribute :title
24
- end
25
-
26
- class NoMatchResource < JSONAPI::Resource
27
- end
28
-
29
- class NoMatchAbstractResource < JSONAPI::Resource
30
- abstract
31
- end
32
-
33
- class CatResource < JSONAPI::Resource
34
- attribute :name
35
- attribute :breed
36
-
37
- has_one :mother, class_name: 'Cat'
38
- has_one :father, class_name: 'Cat'
39
- end
40
-
41
- class PersonWithCustomRecordsForResource < PersonResource
42
- def records_for(relationship_name)
43
- :records_for
44
- end
45
- end
46
-
47
- class PersonWithCustomRecordsForRelationshipsResource < PersonResource
48
- def records_for_posts
49
- :records_for_posts
50
- end
51
-
52
- def record_for_preferences
53
- :record_for_preferences
54
- end
55
- end
56
-
57
- class PersonWithCustomRecordsForErrorResource < PersonResource
58
- class AuthorizationError < StandardError; end
59
- def records_for(relationship_name)
60
- raise AuthorizationError
61
- end
62
- end
63
-
64
- module MyModule
65
- class MyNamespacedResource < JSONAPI::Resource
66
- model_name "Person"
67
- has_many :related
68
- end
69
-
70
- class RelatedResource < JSONAPI::Resource
71
- model_name "Comment"
72
- end
73
- end
74
-
75
- module MyAPI
76
- class MyNamespacedResource < MyModule::MyNamespacedResource
77
- end
78
-
79
- class RelatedResource < MyModule::RelatedResource
80
- end
81
- end
82
-
83
- class ResourceTest < ActiveSupport::TestCase
84
- def setup
85
- @post = Post.first
86
- end
87
-
88
- def test_model_name
89
- assert_equal("Post", PostResource._model_name)
90
- end
91
-
92
- def test_model_name_of_subclassed_non_abstract_resource
93
- assert_equal("Firm", FirmResource._model_name)
94
- end
95
-
96
- def test_model
97
- assert_equal(PostResource._model_class, Post)
98
- end
99
-
100
- def test_module_path
101
- assert_equal(MyModule::MyNamespacedResource.module_path, 'my_module/')
102
- end
103
-
104
- def test_resource_for_root_resource
105
- assert_raises NameError do
106
- JSONAPI::Resource.resource_for('related')
107
- end
108
- end
109
-
110
- def test_resource_for_with_namespaced_paths
111
- assert_equal(JSONAPI::Resource.resource_for('my_module/related'), MyModule::RelatedResource)
112
- assert_equal(PostResource.resource_for('my_module/related'), MyModule::RelatedResource)
113
- assert_equal(MyModule::MyNamespacedResource.resource_for('my_module/related'), MyModule::RelatedResource)
114
- end
115
-
116
- def test_resource_for_resource_does_not_exist_at_root
117
- assert_raises NameError do
118
- ArticleResource.resource_for('related')
119
- end
120
- assert_raises NameError do
121
- JSONAPI::Resource.resource_for('related')
122
- end
123
- end
124
-
125
- def test_resource_for_namespaced_resource
126
- assert_equal(MyModule::MyNamespacedResource.resource_for('related'), MyModule::RelatedResource)
127
- end
128
-
129
- def test_relationship_parent_point_to_correct_resource
130
- assert_equal MyModule::MyNamespacedResource, MyModule::MyNamespacedResource._relationships[:related].parent_resource
131
- end
132
-
133
- def test_relationship_parent_option_point_to_correct_resource
134
- assert_equal MyModule::MyNamespacedResource, MyModule::MyNamespacedResource._relationships[:related].options[:parent_resource]
135
- end
136
-
137
- def test_derived_resources_relationships_parent_point_to_correct_resource
138
- assert_equal MyAPI::MyNamespacedResource, MyAPI::MyNamespacedResource._relationships[:related].parent_resource
139
- end
140
-
141
- def test_derived_resources_relationships_parent_options_point_to_correct_resource
142
- assert_equal MyAPI::MyNamespacedResource, MyAPI::MyNamespacedResource._relationships[:related].options[:parent_resource]
143
- end
144
-
145
- def test_base_resource_abstract
146
- assert BaseResource._abstract
147
- end
148
-
149
- def test_derived_not_abstract
150
- assert PersonResource < BaseResource
151
- refute PersonResource._abstract
152
- end
153
-
154
- def test_nil_model_class
155
- # ToDo:Figure out why this test does not work on Rails 4.0
156
- if Rails::VERSION::MAJOR >= 4 && Rails::VERSION::MINOR >= 1
157
- assert_output nil, "[MODEL NOT FOUND] Model could not be found for NoMatchResource. If this a base Resource declare it as abstract.\n" do
158
- assert_nil NoMatchResource._model_class
159
- end
160
- end
161
- end
162
-
163
- def test_nil_abstract_model_class
164
- assert_output nil, '' do
165
- assert_nil NoMatchAbstractResource._model_class
166
- end
167
- end
168
-
169
- def test_model_alternate
170
- assert_equal(ArticleResource._model_class, Post)
171
- end
172
-
173
- def test_class_attributes
174
- attrs = CatResource._attributes
175
- assert_kind_of(Hash, attrs)
176
- assert_equal(attrs.keys.size, 3)
177
- end
178
-
179
- def test_class_relationships
180
- relationships = CatResource._relationships
181
- assert_kind_of(Hash, relationships)
182
- assert_equal(relationships.size, 2)
183
- end
184
-
185
- def test_find_with_customized_base_records
186
- author = Person.find(1)
187
- posts = ArticleResource.find([], context: author).map(&:_model)
188
-
189
- assert(posts.include?(Post.find(1)))
190
- refute(posts.include?(Post.find(3)))
191
- end
192
-
193
- def test_records_for
194
- author = Person.find(1)
195
- preferences = Preferences.first
196
- refute(preferences == nil)
197
- author.update! preferences: preferences
198
- author_resource = PersonResource.new(author, nil)
199
- assert_equal(author_resource.preferences._model, preferences)
200
-
201
- author_resource = PersonWithCustomRecordsForResource.new(author, nil)
202
- assert_equal(author_resource.preferences._model, :records_for)
203
-
204
- author_resource = PersonWithCustomRecordsForErrorResource.new(author, nil)
205
- assert_raises PersonWithCustomRecordsForErrorResource::AuthorizationError do
206
- author_resource.posts
207
- end
208
- end
209
-
210
- def test_records_for_meta_method_for_to_one
211
- author = Person.find(1)
212
- author.update! preferences: Preferences.first
213
- author_resource = PersonWithCustomRecordsForRelationshipsResource.new(author, nil)
214
- assert_equal(author_resource.record_for_preferences, :record_for_preferences)
215
- end
216
-
217
- def test_records_for_meta_method_for_to_one_calling_records_for
218
- author = Person.find(1)
219
- author.update! preferences: Preferences.first
220
- author_resource = PersonWithCustomRecordsForResource.new(author, nil)
221
- assert_equal(author_resource.record_for_preferences, :records_for)
222
- end
223
-
224
- def test_associated_records_meta_method_for_to_many
225
- author = Person.find(1)
226
- author.posts << Post.find(1)
227
- author_resource = PersonWithCustomRecordsForRelationshipsResource.new(author, nil)
228
- assert_equal(author_resource.records_for_posts, :records_for_posts)
229
- end
230
-
231
- def test_associated_records_meta_method_for_to_many_calling_records_for
232
- author = Person.find(1)
233
- author.posts << Post.find(1)
234
- author_resource = PersonWithCustomRecordsForResource.new(author, nil)
235
- assert_equal(author_resource.records_for_posts, :records_for)
236
- end
237
-
238
- def test_find_by_key_with_customized_base_records
239
- author = Person.find(1)
240
-
241
- post = ArticleResource.find_by_key(1, context: author)._model
242
- assert_equal(post, Post.find(1))
243
-
244
- assert_raises JSONAPI::Exceptions::RecordNotFound do
245
- ArticleResource.find_by_key(3, context: author)._model
246
- end
247
- end
248
-
249
- def test_updatable_fields_does_not_include_id
250
- assert(!CatResource.updatable_fields.include?(:id))
251
- end
252
-
253
- # TODO: Please remove after `updateable_fields` is removed
254
- def test_updateable_fields_delegates_to_updatable_fields_with_deprecation
255
- ActiveSupport::Deprecation.silence do
256
- assert_empty(CatResource.updateable_fields(nil) - [:mother, :father, :name, :breed])
257
- end
258
- end
259
-
260
- # TODO: Please remove after `createable_fields` is removed
261
- def test_createable_fields_delegates_to_creatable_fields_with_deprecation
262
- ActiveSupport::Deprecation.silence do
263
- assert_empty(CatResource.createable_fields(nil) - [:mother, :father, :name, :breed, :id])
264
- end
265
- end
266
-
267
- def test_filter_on_to_many_relationship_id
268
- posts = PostResource.find(:comments => 3)
269
- assert_equal([2], posts.map(&:id))
270
- end
271
-
272
- def test_filter_on_aliased_to_many_relationship_id
273
- # Comment 2 is approved
274
- books = Api::V2::BookResource.find(:aliased_comments => 2)
275
- assert_equal([0], books.map(&:id))
276
-
277
- # However, comment 3 is non-approved, so it won't be accessible through this relationship
278
- books = Api::V2::BookResource.find(:aliased_comments => 3)
279
- assert_equal([], books.map(&:id))
280
- end
281
-
282
- def test_filter_on_has_one_relationship_id
283
- people = PreferencesResource.find(:author => 1)
284
- assert_equal([1], people.map(&:id))
285
- end
286
-
287
- def test_to_many_relationship_filters
288
- post_resource = PostResource.new(Post.find(1), nil)
289
- comments = post_resource.comments
290
- assert_equal(2, comments.size)
291
-
292
- # define apply_filters method on post resource to not respect filters
293
- PostResource.instance_eval do
294
- def apply_filters(records, filters, options)
295
- # :nocov:
296
- records
297
- # :nocov:
298
- end
299
- end
300
-
301
- filtered_comments = post_resource.comments({ filters: { body: 'i liked it' } })
302
- assert_equal(1, filtered_comments.size)
303
-
304
- ensure
305
- # reset method to original implementation
306
- PostResource.instance_eval do
307
- def apply_filters(records, filters, options)
308
- # :nocov:
309
- super
310
- # :nocov:
311
- end
312
- end
313
- end
314
-
315
- def test_to_many_relationship_sorts
316
- post_resource = PostResource.new(Post.find(1), nil)
317
- comment_ids = post_resource.comments.map{|c| c._model.id }
318
- assert_equal [1,2], comment_ids
319
-
320
- # define apply_filters method on post resource to not respect filters
321
- PostResource.instance_eval do
322
- def apply_sort(records, criteria, context = {})
323
- # :nocov:
324
- records
325
- # :nocov:
326
- end
327
- end
328
-
329
- sorted_comment_ids = post_resource.comments(sort_criteria: [{ field: 'id', direction: :desc}]).map{|c| c._model.id }
330
- assert_equal [2,1], sorted_comment_ids
331
-
332
- ensure
333
- # reset method to original implementation
334
- PostResource.instance_eval do
335
- def apply_sort(records, criteria, context = {})
336
- # :nocov:
337
- super
338
- # :nocov:
339
- end
340
- end
341
- end
342
-
343
- def test_to_many_relationship_pagination
344
- post_resource = PostResource.new(Post.find(1), nil)
345
- comments = post_resource.comments
346
- assert_equal 2, comments.size
347
-
348
- # define apply_filters method on post resource to not respect filters
349
- PostResource.instance_eval do
350
- def apply_pagination(records, criteria, order_options)
351
- # :nocov:
352
- records
353
- # :nocov:
354
- end
355
- end
356
-
357
- paginator_class = Class.new(JSONAPI::Paginator) do
358
- def initialize(params)
359
- # param parsing and validation here
360
- @page = params.to_i
361
- end
362
-
363
- def apply(relation, order_options)
364
- relation.offset(@page).limit(1)
365
- end
366
- end
367
-
368
- paged_comments = post_resource.comments(paginator: paginator_class.new(1))
369
- assert_equal 1, paged_comments.size
370
-
371
- ensure
372
- # reset method to original implementation
373
- PostResource.instance_eval do
374
- def apply_pagination(records, criteria, order_options)
375
- # :nocov:
376
- super
377
- # :nocov:
378
- end
379
- end
380
- end
381
-
382
- def test_key_type_integer
383
- CatResource.instance_eval do
384
- key_type :integer
385
- end
386
-
387
- assert CatResource.verify_key('45')
388
- assert CatResource.verify_key(45)
389
-
390
- assert_raises JSONAPI::Exceptions::InvalidFieldValue do
391
- CatResource.verify_key('45,345')
392
- end
393
-
394
- ensure
395
- CatResource.instance_eval do
396
- key_type nil
397
- end
398
- end
399
-
400
- def test_key_type_string
401
- CatResource.instance_eval do
402
- key_type :string
403
- end
404
-
405
- assert CatResource.verify_key('45')
406
- assert CatResource.verify_key(45)
407
-
408
- assert_raises JSONAPI::Exceptions::InvalidFieldValue do
409
- CatResource.verify_key('45,345')
410
- end
411
-
412
- ensure
413
- CatResource.instance_eval do
414
- key_type nil
415
- end
416
- end
417
-
418
- def test_key_type_uuid
419
- CatResource.instance_eval do
420
- key_type :uuid
421
- end
422
-
423
- assert CatResource.verify_key('f1a4d5f2-e77a-4d0a-acbb-ee0b98b3f6b5')
424
-
425
- assert_raises JSONAPI::Exceptions::InvalidFieldValue do
426
- CatResource.verify_key('f1a-e77a-4d0a-acbb-ee0b98b3f6b5')
427
- end
428
-
429
- ensure
430
- CatResource.instance_eval do
431
- key_type nil
432
- end
433
- end
434
-
435
- def test_key_type_proc
436
- CatResource.instance_eval do
437
- key_type -> (key, context) {
438
- return key if key.nil?
439
- if key.to_s.match(/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/)
440
- key
441
- else
442
- raise JSONAPI::Exceptions::InvalidFieldValue.new(:id, key)
443
- end
444
- }
445
- end
446
-
447
- assert CatResource.verify_key('f1a4d5f2-e77a-4d0a-acbb-ee0b98b3f6b5')
448
-
449
- assert_raises JSONAPI::Exceptions::InvalidFieldValue do
450
- CatResource.verify_key('f1a-e77a-4d0a-acbb-ee0b98b3f6b5')
451
- end
452
-
453
- ensure
454
- CatResource.instance_eval do
455
- key_type nil
456
- end
457
- end
458
-
459
- def test_id_attr_deprecation
460
- _out, err = capture_io do
461
- eval <<-CODE
462
- class ProblemResource < JSONAPI::Resource
463
- attribute :id
464
- end
465
- CODE
466
- end
467
- assert_match /DEPRECATION WARNING: Id without format is no longer supported. Please remove ids from attributes, or specify a format./, err
468
- end
469
-
470
- def test_id_attr_with_format
471
- _out, err = capture_io do
472
- eval <<-CODE
473
- class NotProblemResource < JSONAPI::Resource
474
- attribute :id, format: :string
475
- end
476
- CODE
477
- end
478
- assert_equal "", err
479
- end
480
-
481
- def test_links_resource_warning
482
- _out, err = capture_io do
483
- eval "class LinksResource < JSONAPI::Resource; end"
484
- end
485
- assert_match /LinksResource` is a reserved resource name/, err
486
- end
487
-
488
- def test_reserved_key_warnings
489
- _out, err = capture_io do
490
- eval <<-CODE
491
- class BadlyNamedAttributesResource < JSONAPI::Resource
492
- attributes :type
493
- end
494
- CODE
495
- end
496
- assert_match /`type` is a reserved key in ./, err
497
- end
498
-
499
- def test_reserved_relationship_warnings
500
- %w(id type).each do |key|
501
- _out, err = capture_io do
502
- eval <<-CODE
503
- class BadlyNamedAttributesResource < JSONAPI::Resource
504
- has_one :#{key}
505
- end
506
- CODE
507
- end
508
- assert_match /`#{key}` is a reserved relationship name in ./, err
509
- end
510
- %w(types ids).each do |key|
511
- _out, err = capture_io do
512
- eval <<-CODE
513
- class BadlyNamedAttributesResource < JSONAPI::Resource
514
- has_many :#{key}
515
- end
516
- CODE
517
- end
518
- assert_match /`#{key}` is a reserved relationship name in ./, err
519
- end
520
- end
521
-
522
- def test_abstract_warning
523
- _out, err = capture_io do
524
- eval <<-CODE
525
- class NoModelResource < JSONAPI::Resource
526
- end
527
- NoModelResource._model_class
528
- CODE
529
- end
530
- assert_match "[MODEL NOT FOUND] Model could not be found for ResourceTest::NoModelResource. If this a base Resource declare it as abstract.\n", err
531
- end
532
-
533
- def test_no_warning_when_abstract
534
- _out, err = capture_io do
535
- eval <<-CODE
536
- class NoModelAbstractResource < JSONAPI::Resource
537
- abstract
538
- end
539
- NoModelAbstractResource._model_class
540
- CODE
541
- end
542
- assert_match "", err
543
- end
544
-
545
- def test_correct_error_surfaced_if_validation_errors_in_after_save_callback
546
- post = PostWithBadAfterSave.find(1)
547
- post_resource = ArticleWithBadAfterSaveResource.new(post, nil)
548
- err = assert_raises JSONAPI::Exceptions::ValidationErrors do
549
- post_resource.replace_fields({:attributes => {:title => 'Some title'}})
550
- end
551
- assert_equal(err.error_messages[:base], ['Boom! Error added in after_save callback.'])
552
- end
553
-
554
- def test_resource_for_model_use_hint
555
- special_person = Person.create!(name: 'Special', date_joined: Date.today, special: true)
556
- special_resource = SpecialPersonResource.new(special_person, nil)
557
- resource_model = SpecialPersonResource.records({}).first # simulate a find
558
- assert_equal(SpecialPersonResource, SpecialPersonResource.resource_for_model(resource_model))
559
- end
560
- end