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,1486 +0,0 @@
1
- require 'active_record'
2
- require 'jsonapi-resources'
3
-
4
- ActiveSupport::Inflector.inflections(:en) do |inflect|
5
- inflect.uncountable 'preferences'
6
- inflect.irregular 'numero_telefone', 'numeros_telefone'
7
- end
8
-
9
- ### DATABASE
10
- ActiveRecord::Schema.define do
11
- create_table :people, force: true do |t|
12
- t.string :name
13
- t.string :email
14
- t.datetime :date_joined
15
- t.belongs_to :preferences
16
- t.integer :hair_cut_id, index: true
17
- t.boolean :book_admin, default: false
18
- t.boolean :special, default: false
19
- t.timestamps null: false
20
- end
21
-
22
- create_table :author_details, force: true do |t|
23
- t.integer :person_id
24
- t.string :author_stuff
25
- end
26
-
27
- create_table :posts, force: true do |t|
28
- t.string :title
29
- t.text :body
30
- t.integer :author_id
31
- t.belongs_to :section, index: true
32
- t.timestamps null: false
33
- end
34
-
35
- create_table :comments, force: true do |t|
36
- t.text :body
37
- t.belongs_to :post, index: true
38
- t.integer :author_id
39
- t.timestamps null: false
40
- end
41
-
42
- create_table :companies, force: true do |t|
43
- t.string :type
44
- t.string :name
45
- t.string :address
46
- t.timestamps null: false
47
- end
48
-
49
- create_table :tags, force: true do |t|
50
- t.string :name
51
- end
52
-
53
- create_table :sections, force: true do |t|
54
- t.string :name
55
- end
56
-
57
- create_table :posts_tags, force: true do |t|
58
- t.references :post, :tag, index: true
59
- end
60
- add_index :posts_tags, [:post_id, :tag_id], unique: true
61
-
62
- create_table :special_post_tags, force: true do |t|
63
- t.references :post, :tag, index: true
64
- end
65
- add_index :special_post_tags, [:post_id, :tag_id], unique: true
66
-
67
- create_table :comments_tags, force: true do |t|
68
- t.references :comment, :tag, index: true
69
- end
70
-
71
- create_table :iso_currencies, id: false, force: true do |t|
72
- t.string :code, limit: 3, null: false
73
- t.string :name
74
- t.string :country_name
75
- t.string :minor_unit
76
- t.timestamps null: false
77
- end
78
- add_index :iso_currencies, :code, unique: true
79
-
80
- create_table :expense_entries, force: true do |t|
81
- t.string :currency_code, limit: 3, null: false
82
- t.integer :employee_id, null: false
83
- t.decimal :cost, precision: 12, scale: 4, null: false
84
- t.date :transaction_date
85
- end
86
-
87
- create_table :planets, force: true do |t|
88
- t.string :name
89
- t.string :description
90
- t.integer :planet_type_id
91
- end
92
-
93
- create_table :planets_tags, force: true do |t|
94
- t.references :planet, :tag, index: true
95
- end
96
- add_index :planets_tags, [:planet_id, :tag_id], unique: true
97
-
98
- create_table :planet_types, force: true do |t|
99
- t.string :name
100
- end
101
-
102
- create_table :moons, force: true do |t|
103
- t.string :name
104
- t.string :description
105
- t.integer :planet_id
106
- end
107
-
108
- create_table :craters, id: false, force: true do |t|
109
- t.string :code
110
- t.string :description
111
- t.integer :moon_id
112
- end
113
-
114
- create_table :preferences, force: true do |t|
115
- t.integer :person_id
116
- t.boolean :advanced_mode, default: false
117
- end
118
-
119
- create_table :facts, force: true do |t|
120
- t.integer :person_id
121
- t.string :spouse_name
122
- t.text :bio
123
- t.float :quality_rating
124
- t.decimal :salary, precision: 12, scale: 2
125
- t.datetime :date_time_joined
126
- t.date :birthday
127
- t.time :bedtime
128
- t.binary :photo, limit: 1.kilobyte
129
- t.boolean :cool
130
- end
131
-
132
- create_table :books, force: true do |t|
133
- t.string :title
134
- t.string :isbn
135
- t.boolean :banned, default: false
136
- end
137
-
138
- create_table :book_authors, force: true do |t|
139
- t.integer :book_id
140
- t.integer :person_id
141
- end
142
-
143
- create_table :book_comments, force: true do |t|
144
- t.text :body
145
- t.belongs_to :book, index: true
146
- t.integer :author_id
147
- t.boolean :approved, default: true
148
- t.timestamps null: false
149
- end
150
-
151
- create_table :customers, force: true do |t|
152
- t.string :name
153
- end
154
-
155
- create_table :purchase_orders, force: true do |t|
156
- t.date :order_date
157
- t.date :requested_delivery_date
158
- t.date :delivery_date
159
- t.integer :customer_id
160
- t.string :delivery_name
161
- t.string :delivery_address_1
162
- t.string :delivery_address_2
163
- t.string :delivery_city
164
- t.string :delivery_state
165
- t.string :delivery_postal_code
166
- t.float :delivery_fee
167
- t.float :tax
168
- t.float :total
169
- t.timestamps null: false
170
- end
171
-
172
- create_table :order_flags, force: true do |t|
173
- t.string :name
174
- end
175
-
176
- create_table :purchase_orders_order_flags, force: true do |t|
177
- t.references :purchase_order, :order_flag, index: true
178
- end
179
- add_index :purchase_orders_order_flags, [:purchase_order_id, :order_flag_id], unique: true, name: "po_flags_idx"
180
-
181
- create_table :line_items, force: true do |t|
182
- t.integer :purchase_order_id
183
- t.string :part_number
184
- t.string :quantity
185
- t.float :item_cost
186
- t.timestamps null: false
187
- end
188
-
189
- create_table :hair_cuts, force: true do |t|
190
- t.string :style
191
- end
192
-
193
- create_table :numeros_telefone, force: true do |t|
194
- t.string :numero_telefone
195
- t.timestamps null: false
196
- end
197
-
198
- create_table :categories, force: true do |t|
199
- t.string :name
200
- t.string :status, limit: 10
201
- end
202
-
203
- create_table :pictures, force: true do |t|
204
- t.string :name
205
- t.integer :imageable_id
206
- t.string :imageable_type
207
- t.timestamps null: false
208
- end
209
-
210
- create_table :documents, force: true do |t|
211
- t.string :name
212
- t.timestamps null: false
213
- end
214
-
215
- create_table :products, force: true do |t|
216
- t.string :name
217
- t.timestamps null: false
218
- end
219
-
220
- create_table :vehicles, force: true do |t|
221
- t.string :type
222
- t.string :make
223
- t.string :model
224
- t.string :length_at_water_line
225
- t.string :drive_layout
226
- t.string :serial_number
227
- t.integer :person_id
228
- end
229
-
230
- create_table :makes, force: true do |t|
231
- t.string :model
232
- end
233
-
234
- # special cases - fields that look like they should be reserved names
235
- create_table :hrefs, force: true do |t|
236
- t.string :name
237
- end
238
-
239
- create_table :links, force: true do |t|
240
- t.string :name
241
- end
242
-
243
- create_table :web_pages, force: true do |t|
244
- t.string :href
245
- t.string :link
246
- end
247
-
248
- create_table :questionables, force: true do |t|
249
- end
250
- # special cases
251
- end
252
-
253
- ### MODELS
254
- class Person < ActiveRecord::Base
255
- has_many :posts, foreign_key: 'author_id'
256
- has_many :comments, foreign_key: 'author_id'
257
- has_many :expense_entries, foreign_key: 'employee_id', dependent: :restrict_with_exception
258
- has_many :vehicles
259
- belongs_to :preferences
260
- belongs_to :hair_cut
261
- has_one :author_detail
262
-
263
- has_and_belongs_to_many :books, join_table: :book_authors
264
-
265
- ### Validations
266
- validates :name, presence: true
267
- validates :date_joined, presence: true
268
- end
269
-
270
- class AuthorDetail < ActiveRecord::Base
271
- belongs_to :author, class_name: 'Person', foreign_key: 'person_id'
272
- end
273
-
274
- class Post < ActiveRecord::Base
275
- belongs_to :author, class_name: 'Person', foreign_key: 'author_id'
276
- belongs_to :writer, class_name: 'Person', foreign_key: 'author_id'
277
- has_many :comments
278
- has_and_belongs_to_many :tags, join_table: :posts_tags
279
- has_many :special_post_tags, source: :tag
280
- has_many :special_tags, through: :special_post_tags, source: :tag
281
- belongs_to :section
282
-
283
- validates :author, presence: true
284
- validates :title, length: { maximum: 35 }
285
-
286
- before_destroy :destroy_callback
287
-
288
- def destroy_callback
289
- if title == "can't destroy me"
290
- errors.add(:title, "can't destroy me")
291
- return false
292
- end
293
- end
294
- end
295
-
296
- class SpecialPostTag < ActiveRecord::Base
297
- belongs_to :tag
298
- belongs_to :post
299
- end
300
-
301
- class Comment < ActiveRecord::Base
302
- belongs_to :author, class_name: 'Person', foreign_key: 'author_id'
303
- belongs_to :post
304
- has_and_belongs_to_many :tags, join_table: :comments_tags
305
- end
306
-
307
- class Company < ActiveRecord::Base
308
- end
309
-
310
- class Firm < Company
311
- end
312
-
313
- class Tag < ActiveRecord::Base
314
- has_and_belongs_to_many :posts, join_table: :posts_tags
315
- has_and_belongs_to_many :planets, join_table: :planets_tags
316
- end
317
-
318
- class Section < ActiveRecord::Base
319
- end
320
-
321
- class HairCut < ActiveRecord::Base
322
- end
323
-
324
- class Property < ActiveRecord::Base
325
- end
326
-
327
- class Customer < ActiveRecord::Base
328
- end
329
-
330
- class BadlyNamedAttributes < ActiveRecord::Base
331
- end
332
-
333
- class Cat < ActiveRecord::Base
334
- end
335
-
336
- class IsoCurrency < ActiveRecord::Base
337
- self.primary_key = :code
338
- # has_many :expense_entries, foreign_key: 'currency_code'
339
- end
340
-
341
- class ExpenseEntry < ActiveRecord::Base
342
- belongs_to :employee, class_name: 'Person', foreign_key: 'employee_id'
343
- belongs_to :iso_currency, foreign_key: 'currency_code'
344
- end
345
-
346
- class Planet < ActiveRecord::Base
347
- has_many :moons
348
- belongs_to :planet_type
349
-
350
- has_and_belongs_to_many :tags, join_table: :planets_tags
351
-
352
- # Test model callback cancelling save
353
- before_save :check_not_pluto
354
-
355
- def check_not_pluto
356
- # Pluto can't be a planet, so cancel the save
357
- if name.downcase == 'pluto'
358
- return false
359
- end
360
- end
361
- end
362
-
363
- class PlanetType < ActiveRecord::Base
364
- has_many :planets
365
- end
366
-
367
- class Moon < ActiveRecord::Base
368
- belongs_to :planet
369
-
370
- has_many :craters
371
- end
372
-
373
- class Crater < ActiveRecord::Base
374
- self.primary_key = :code
375
-
376
- belongs_to :moon
377
- end
378
-
379
- class Preferences < ActiveRecord::Base
380
- has_one :author, class_name: 'Person', :inverse_of => 'preferences'
381
- end
382
-
383
- class Fact < ActiveRecord::Base
384
- validates :spouse_name, :bio, presence: true
385
- end
386
-
387
- class Like < ActiveRecord::Base
388
- end
389
-
390
- class Breed
391
-
392
- def initialize(id = nil, name = nil)
393
- if id.nil?
394
- @id = $breed_data.new_id
395
- $breed_data.add(self)
396
- else
397
- @id = id
398
- end
399
- @name = name
400
- @errors = ActiveModel::Errors.new(self)
401
- end
402
-
403
- attr_accessor :id, :name
404
-
405
- def destroy
406
- $breed_data.remove(@id)
407
- end
408
-
409
- def valid?
410
- @errors.clear
411
- if name.is_a?(String) && name.length > 0
412
- return true
413
- else
414
- @errors.set(:name, ["can't be blank"])
415
- return false
416
- end
417
- end
418
-
419
- def errors
420
- @errors
421
- end
422
- end
423
-
424
- class Book < ActiveRecord::Base
425
- has_many :book_comments
426
- has_many :approved_book_comments, -> { where(approved: true) }, class_name: "BookComment"
427
-
428
- has_and_belongs_to_many :authors, join_table: :book_authors, class_name: "Person"
429
- end
430
-
431
- class BookComment < ActiveRecord::Base
432
- belongs_to :author, class_name: 'Person', foreign_key: 'author_id'
433
- belongs_to :book
434
-
435
- def self.for_user(current_user)
436
- records = self
437
- # Hide the unapproved comments from people who are not book admins
438
- unless current_user && current_user.book_admin
439
- records = records.where(approved: true)
440
- end
441
- records
442
- end
443
- end
444
-
445
- class BreedData
446
- def initialize
447
- @breeds = {}
448
- end
449
-
450
- def breeds
451
- @breeds
452
- end
453
-
454
- def new_id
455
- @breeds.keys.max + 1
456
- end
457
-
458
- def add(breed)
459
- @breeds[breed.id] = breed
460
- end
461
-
462
- def remove(id)
463
- @breeds.delete(id)
464
- end
465
- end
466
-
467
- class Customer < ActiveRecord::Base
468
- has_many :purchase_orders
469
- end
470
-
471
- class PurchaseOrder < ActiveRecord::Base
472
- belongs_to :customer
473
- has_many :line_items
474
- has_many :admin_line_items, class_name: 'LineItem', foreign_key: 'purchase_order_id'
475
-
476
- has_and_belongs_to_many :order_flags, join_table: :purchase_orders_order_flags
477
-
478
- has_and_belongs_to_many :admin_order_flags, join_table: :purchase_orders_order_flags, class_name: 'OrderFlag'
479
- end
480
-
481
- class OrderFlag < ActiveRecord::Base
482
- has_and_belongs_to_many :purchase_orders, join_table: :purchase_orders_order_flags
483
- end
484
-
485
- class LineItem < ActiveRecord::Base
486
- belongs_to :purchase_order
487
- end
488
-
489
- class NumeroTelefone < ActiveRecord::Base
490
- end
491
-
492
- class Category < ActiveRecord::Base
493
- end
494
-
495
- class Picture < ActiveRecord::Base
496
- belongs_to :imageable, polymorphic: true
497
- end
498
-
499
- class Vehicle < ActiveRecord::Base
500
- belongs_to :person
501
- end
502
-
503
- class Car < Vehicle
504
- end
505
-
506
- class Boat < Vehicle
507
- end
508
-
509
- class Document < ActiveRecord::Base
510
- has_many :pictures, as: :imageable
511
- end
512
-
513
- class Product < ActiveRecord::Base
514
- has_one :picture, as: :imageable
515
- end
516
-
517
- class Make < ActiveRecord::Base
518
- end
519
-
520
- class WebPage < ActiveRecord::Base
521
- end
522
-
523
- module Api
524
- module V7
525
- class Client < Customer
526
- end
527
-
528
- class Customer < Customer
529
- end
530
- end
531
- end
532
-
533
- ### OperationsProcessor
534
- class CountingActiveRecordOperationsProcessor < ActiveRecordOperationsProcessor
535
- after_find_operation do
536
- @operation_meta[:total_records] = @operation.record_count
537
- @operation_links['spec'] = 'https://test_corp.com'
538
- end
539
- end
540
-
541
- # This processor swaps in a mock for the operation that will raise an exception
542
- # when it receives the :apply method. This is used to test the
543
- # exception_class_whitelist configuration.
544
- class ErrorRaisingOperationsProcessor < ActiveRecordOperationsProcessor
545
- def process_operation(operation)
546
- mock_operation = Minitest::Mock.new
547
- mock_operation.expect(:apply, true) do
548
- raise PostsController::SubSpecialError
549
- end
550
- super(mock_operation)
551
- end
552
- end
553
-
554
- ### CONTROLLERS
555
- class AuthorsController < JSONAPI::ResourceController
556
- end
557
-
558
- class PeopleController < JSONAPI::ResourceController
559
- end
560
-
561
- class BaseController < ActionController::Base
562
- include JSONAPI::ActsAsResourceController
563
- end
564
-
565
- class PostsController < BaseController
566
-
567
- class SpecialError < StandardError; end
568
- class SubSpecialError < PostsController::SpecialError; end
569
-
570
- # This is used to test that classes that are whitelisted are reraised by
571
- # the operations processor.
572
- rescue_from PostsController::SpecialError do
573
- head :forbidden
574
- end
575
-
576
- def handle_exceptions(e)
577
- case e
578
- when PostsController::SpecialError
579
- raise e
580
- else
581
- super(e)
582
- end
583
- end
584
-
585
- #called by test_on_server_error
586
- def self.set_callback_message(error)
587
- @callback_message = "Sent from method"
588
- end
589
- end
590
-
591
- class CommentsController < JSONAPI::ResourceController
592
- end
593
-
594
- class FirmsController < JSONAPI::ResourceController
595
- end
596
-
597
- class SectionsController < JSONAPI::ResourceController
598
- end
599
-
600
- class TagsController < JSONAPI::ResourceController
601
- end
602
-
603
- class IsoCurrenciesController < JSONAPI::ResourceController
604
- end
605
-
606
- class ExpenseEntriesController < JSONAPI::ResourceController
607
- end
608
-
609
- class BreedsController < JSONAPI::ResourceController
610
- end
611
-
612
- class FactsController < JSONAPI::ResourceController
613
- end
614
-
615
- class CategoriesController < JSONAPI::ResourceController
616
- end
617
-
618
- class PicturesController < JSONAPI::ResourceController
619
- end
620
-
621
- class DocumentsController < JSONAPI::ResourceController
622
- end
623
-
624
- class ProductsController < JSONAPI::ResourceController
625
- end
626
-
627
- class ImageablesController < JSONAPI::ResourceController
628
- end
629
-
630
- class VehiclesController < JSONAPI::ResourceController
631
- end
632
-
633
- class CarsController < JSONAPI::ResourceController
634
- end
635
-
636
- class BoatsController < JSONAPI::ResourceController
637
- end
638
-
639
- class BooksController < JSONAPI::ResourceController
640
- end
641
-
642
- class AuthorsController < JSONAPI::ResourceController
643
- end
644
-
645
- ### CONTROLLERS
646
- module Api
647
- module V1
648
- class AuthorsController < JSONAPI::ResourceController
649
- end
650
-
651
- class PeopleController < JSONAPI::ResourceController
652
- end
653
-
654
- class PostsController < ActionController::Base
655
- include JSONAPI::ActsAsResourceController
656
- end
657
-
658
- class TagsController < JSONAPI::ResourceController
659
- end
660
-
661
- class IsoCurrenciesController < JSONAPI::ResourceController
662
- end
663
-
664
- class ExpenseEntriesController < JSONAPI::ResourceController
665
- end
666
-
667
- class BreedsController < JSONAPI::ResourceController
668
- end
669
-
670
- class PlanetsController < JSONAPI::ResourceController
671
- end
672
-
673
- class PlanetTypesController < JSONAPI::ResourceController
674
- end
675
-
676
- class MoonsController < JSONAPI::ResourceController
677
- end
678
-
679
- class CratersController < JSONAPI::ResourceController
680
- end
681
-
682
- class LikesController < JSONAPI::ResourceController
683
- end
684
- end
685
-
686
- module V2
687
- class AuthorsController < JSONAPI::ResourceController
688
- end
689
-
690
- class PeopleController < JSONAPI::ResourceController
691
- end
692
-
693
- class PostsController < JSONAPI::ResourceController
694
- end
695
-
696
- class PreferencesController < JSONAPI::ResourceController
697
- end
698
-
699
- class BooksController < JSONAPI::ResourceController
700
- def context
701
- {current_user: $test_user}
702
- end
703
- end
704
-
705
- class BookCommentsController < JSONAPI::ResourceController
706
- def context
707
- {current_user: $test_user}
708
- end
709
- end
710
- end
711
-
712
- module V3
713
- class PostsController < JSONAPI::ResourceController
714
- end
715
- end
716
-
717
- module V4
718
- class PostsController < JSONAPI::ResourceController
719
- end
720
-
721
- class ExpenseEntriesController < JSONAPI::ResourceController
722
- end
723
-
724
- class IsoCurrenciesController < JSONAPI::ResourceController
725
- end
726
-
727
- class BooksController < JSONAPI::ResourceController
728
- end
729
- end
730
-
731
- module V5
732
- class AuthorsController < JSONAPI::ResourceController
733
- def serialization_options
734
- {foo: 'bar'}
735
- end
736
- end
737
-
738
- class PostsController < JSONAPI::ResourceController
739
- end
740
-
741
- class ExpenseEntriesController < JSONAPI::ResourceController
742
- end
743
-
744
- class IsoCurrenciesController < JSONAPI::ResourceController
745
- end
746
- end
747
-
748
- module V6
749
- class CustomersController < JSONAPI::ResourceController
750
- end
751
-
752
- class PurchaseOrdersController < JSONAPI::ResourceController
753
- def context
754
- {current_user: $test_user}
755
- end
756
- end
757
-
758
- class LineItemsController < JSONAPI::ResourceController
759
- end
760
-
761
- class OrderFlagsController < JSONAPI::ResourceController
762
- end
763
- end
764
-
765
- module V7
766
- class CustomersController < JSONAPI::ResourceController
767
- end
768
-
769
- class PurchaseOrdersController < JSONAPI::ResourceController
770
- end
771
-
772
- class LineItemsController < JSONAPI::ResourceController
773
- end
774
-
775
- class OrderFlagsController < JSONAPI::ResourceController
776
- end
777
-
778
- class CategoriesController < JSONAPI::ResourceController
779
- end
780
-
781
- class ClientsController < JSONAPI::ResourceController
782
- end
783
- end
784
-
785
- module V8
786
- class NumerosTelefoneController < JSONAPI::ResourceController
787
- end
788
- end
789
- end
790
-
791
- ### RESOURCES
792
- class BaseResource < JSONAPI::Resource
793
- abstract
794
- end
795
-
796
- class PersonResource < BaseResource
797
- attributes :name, :email
798
- attribute :date_joined, format: :date_with_timezone
799
-
800
- has_many :comments
801
- has_many :posts
802
- has_many :vehicles, polymorphic: true
803
-
804
- has_one :preferences
805
- has_one :hair_cut
806
-
807
- filter :name, verify: ->(values, _context) {
808
- values.each do |value|
809
- if value.length < 3
810
- raise JSONAPI::Exceptions::InvalidFilterValue.new(:name, value)
811
- end
812
- end
813
- return values
814
- }
815
- end
816
-
817
- class SpecialBaseResource < BaseResource
818
- abstract
819
-
820
- model_hint model: Person, resource: :special_person
821
- end
822
-
823
- class SpecialPersonResource < SpecialBaseResource
824
- model_name 'Person'
825
-
826
- def self.records(options = {})
827
- Person.where(special: true)
828
- end
829
- end
830
-
831
- class VehicleResource < JSONAPI::Resource
832
- immutable
833
-
834
- has_one :person
835
- attributes :make, :model, :serial_number
836
- end
837
-
838
- class CarResource < VehicleResource
839
- attributes :drive_layout
840
- end
841
-
842
- class BoatResource < VehicleResource
843
- attributes :length_at_water_line
844
- end
845
-
846
- class CommentResource < JSONAPI::Resource
847
- attributes :body
848
- has_one :post
849
- has_one :author, class_name: 'Person'
850
- has_many :tags
851
-
852
- filters :body
853
- end
854
-
855
- class CompanyResource < JSONAPI::Resource
856
- attributes :name, :address
857
- end
858
-
859
- class FirmResource < CompanyResource
860
- end
861
-
862
- class TagResource < JSONAPI::Resource
863
- attributes :name
864
-
865
- has_many :posts
866
- # Not including the planets relationship so they don't get output
867
- #has_many :planets
868
- end
869
-
870
- class SectionResource < JSONAPI::Resource
871
- attributes 'name'
872
- end
873
-
874
- class PostResource < JSONAPI::Resource
875
- attribute :title
876
- attribute :body
877
- attribute :subject
878
-
879
- has_one :author, class_name: 'Person'
880
- has_one :section
881
- has_many :tags, acts_as_set: true
882
- has_many :comments, acts_as_set: false
883
-
884
-
885
- # Not needed - just for testing
886
- primary_key :id
887
-
888
- before_save do
889
- msg = "Before save"
890
- end
891
-
892
- after_save do
893
- msg = "After save"
894
- end
895
-
896
- before_update do
897
- msg = "Before update"
898
- end
899
-
900
- after_update do
901
- msg = "After update"
902
- end
903
-
904
- before_replace_fields do
905
- msg = "Before replace_fields"
906
- end
907
-
908
- after_replace_fields do
909
- msg = "After replace_fields"
910
- end
911
-
912
- around_update :around_update_check
913
-
914
- def around_update_check
915
- # do nothing
916
- yield
917
- # do nothing
918
- end
919
-
920
- def subject
921
- @model.title
922
- end
923
-
924
- def title=(title)
925
- @model.title = title
926
- if title == 'BOOM'
927
- raise 'The Server just tested going boom. If this was a real emergency you would be really dead right now.'
928
- end
929
- end
930
-
931
- filters :title, :author, :tags, :comments
932
- filter :id, verify: ->(values, context) {
933
- verify_keys(values, context)
934
- return values
935
- }
936
- filter :ids,
937
- verify: ->(values, context) {
938
- verify_keys(values, context)
939
- return values
940
- },
941
- apply: -> (records, value, _options) {
942
- records.where('id IN (?)', value)
943
- }
944
-
945
- def self.updatable_fields(context)
946
- super(context) - [:author, :subject]
947
- end
948
-
949
- def self.creatable_fields(context)
950
- super(context) - [:subject]
951
- end
952
-
953
- def self.sortable_fields(context)
954
- super(context) - [:id]
955
- end
956
-
957
- def self.verify_key(key, context = nil)
958
- super(key)
959
- raise JSONAPI::Exceptions::RecordNotFound.new(key) unless find_by_key(key, context: context)
960
- return key
961
- end
962
- end
963
-
964
- class HairCutResource < JSONAPI::Resource
965
- attribute :style
966
- has_many :people
967
- end
968
-
969
- class IsoCurrencyResource < JSONAPI::Resource
970
- attributes :name, :country_name, :minor_unit
971
-
972
- filter :country_name
973
-
974
- key_type :string
975
- end
976
-
977
- class ExpenseEntryResource < JSONAPI::Resource
978
- attributes :cost
979
- attribute :transaction_date, format: :date
980
-
981
- has_one :iso_currency, foreign_key: 'currency_code'
982
- has_one :employee, class_name: 'Person'
983
- end
984
-
985
- class EmployeeResource < JSONAPI::Resource
986
- attributes :name, :email
987
- model_name 'Person'
988
- end
989
-
990
- class BreedResource < JSONAPI::Resource
991
- attribute :name, format: :title
992
-
993
- # This is unneeded, just here for testing
994
- routing_options param: :id
995
-
996
- def self.find(filters, options = {})
997
- breeds = []
998
- $breed_data.breeds.values.each do |breed|
999
- breeds.push(BreedResource.new(breed, options[:context]))
1000
- end
1001
- breeds
1002
- end
1003
-
1004
- def self.find_by_key(id, options = {})
1005
- BreedResource.new($breed_data.breeds[id.to_i], options[:context])
1006
- end
1007
-
1008
- def _save
1009
- super
1010
- return :accepted
1011
- end
1012
- end
1013
-
1014
- class PlanetResource < JSONAPI::Resource
1015
- attribute :name
1016
- attribute :description
1017
-
1018
- has_many :moons
1019
- has_one :planet_type
1020
-
1021
- has_many :tags, acts_as_set: true
1022
-
1023
- def records_for_moons
1024
- Moon.joins(:craters).select('moons.*, craters.code').distinct
1025
- end
1026
- end
1027
-
1028
- class PropertyResource < JSONAPI::Resource
1029
- attributes :name
1030
-
1031
- has_many :planets
1032
- end
1033
-
1034
- class PlanetTypeResource < JSONAPI::Resource
1035
- attributes :name
1036
- has_many :planets
1037
- end
1038
-
1039
- class MoonResource < JSONAPI::Resource
1040
- attribute :name
1041
- attribute :description
1042
-
1043
- has_one :planet
1044
- has_many :craters
1045
- end
1046
-
1047
- class CraterResource < JSONAPI::Resource
1048
- attribute :code
1049
- attribute :description
1050
-
1051
- has_one :moon
1052
-
1053
- def self.verify_key(key, context = nil)
1054
- key && String(key)
1055
- end
1056
- end
1057
-
1058
- class PreferencesResource < JSONAPI::Resource
1059
- attribute :advanced_mode
1060
-
1061
- has_one :author, :foreign_key_on => :related
1062
-
1063
- def self.find_by_key(key, options = {})
1064
- new(Preferences.first, nil)
1065
- end
1066
- end
1067
-
1068
- class FactResource < JSONAPI::Resource
1069
- attribute :spouse_name
1070
- attribute :bio
1071
- attribute :quality_rating
1072
- attribute :salary
1073
- attribute :date_time_joined
1074
- attribute :birthday
1075
- attribute :bedtime
1076
- attribute :photo
1077
- attribute :cool
1078
- end
1079
-
1080
- class CategoryResource < JSONAPI::Resource
1081
- filter :status, default: 'active'
1082
- end
1083
-
1084
- class PictureResource < JSONAPI::Resource
1085
- attribute :name
1086
- has_one :imageable, polymorphic: true
1087
- end
1088
-
1089
- class DocumentResource < JSONAPI::Resource
1090
- attribute :name
1091
- has_many :pictures
1092
- end
1093
-
1094
- class ProductResource < JSONAPI::Resource
1095
- attribute :name
1096
- has_one :picture, always_include_linkage_data: true
1097
-
1098
- def picture_id
1099
- _model.picture.id
1100
- end
1101
- end
1102
-
1103
- class ImageableResource < JSONAPI::Resource
1104
- end
1105
-
1106
- class MakeResource < JSONAPI::Resource
1107
- attribute :model
1108
- end
1109
-
1110
- class WebPageResource < JSONAPI::Resource
1111
- attribute :href
1112
- attribute :link
1113
- end
1114
-
1115
- class AuthorResource < JSONAPI::Resource
1116
- model_name 'Person'
1117
- attributes :name
1118
- end
1119
-
1120
- class BookResource < JSONAPI::Resource
1121
- has_many :authors, class_name: 'Author'
1122
- end
1123
-
1124
- class AuthorDetailResource < JSONAPI::Resource
1125
- attributes :author_stuff
1126
- end
1127
-
1128
- module Api
1129
- module V1
1130
- class WriterResource < JSONAPI::Resource
1131
- attributes :name, :email
1132
- model_name 'Person'
1133
- has_many :posts
1134
-
1135
- filter :name
1136
- end
1137
-
1138
- class LikeResource < JSONAPI::Resource
1139
- end
1140
-
1141
- class PostResource < JSONAPI::Resource
1142
- # V1 no longer supports tags and now calls author 'writer'
1143
- attribute :title
1144
- attribute :body
1145
- attribute :subject
1146
-
1147
- has_one :writer, foreign_key: 'author_id', class_name: 'Writer'
1148
- has_one :section
1149
- has_many :comments, acts_as_set: false
1150
-
1151
- def subject
1152
- @model.title
1153
- end
1154
-
1155
- filters :writer
1156
- end
1157
-
1158
- class PersonResource < PersonResource; end
1159
- class CommentResource < CommentResource; end
1160
- class TagResource < TagResource; end
1161
- class SectionResource < SectionResource; end
1162
- class IsoCurrencyResource < IsoCurrencyResource; end
1163
- class ExpenseEntryResource < ExpenseEntryResource; end
1164
- class BreedResource < BreedResource; end
1165
- class PlanetResource < PlanetResource; end
1166
- class PlanetTypeResource < PlanetTypeResource; end
1167
- class MoonResource < MoonResource; end
1168
- class CraterResource < CraterResource; end
1169
- class PreferencesResource < PreferencesResource; end
1170
- class EmployeeResource < EmployeeResource; end
1171
- class HairCutResource < HairCutResource; end
1172
- class VehicleResource < VehicleResource; end
1173
- class CarResource < CarResource; end
1174
- class BoatResource < BoatResource; end
1175
- end
1176
- end
1177
-
1178
- module Api
1179
- module V2
1180
- class PreferencesResource < PreferencesResource; end
1181
- class PersonResource < PersonResource; end
1182
- class PostResource < PostResource; end
1183
-
1184
- class BookResource < JSONAPI::Resource
1185
- attribute :title
1186
- attributes :isbn, :banned
1187
-
1188
- has_many :book_comments, relation_name: -> (options = {}) {
1189
- context = options[:context]
1190
- current_user = context ? context[:current_user] : nil
1191
-
1192
- unless current_user && current_user.book_admin
1193
- :approved_book_comments
1194
- else
1195
- :book_comments
1196
- end
1197
- }
1198
-
1199
- has_many :aliased_comments, class_name: 'BookComments', relation_name: :approved_book_comments
1200
-
1201
- filters :book_comments
1202
- filter :banned, apply: ->(records, value, options) {
1203
- context = options[:context]
1204
- current_user = context ? context[:current_user] : nil
1205
-
1206
- # Only book admins my filter for banned books
1207
- if current_user && current_user.book_admin
1208
- records.where('books.banned = ?', value[0] == 'true')
1209
- end
1210
- }
1211
-
1212
- class << self
1213
- def books
1214
- Book.arel_table
1215
- end
1216
-
1217
- def not_banned_books
1218
- books[:banned].eq(false)
1219
- end
1220
-
1221
- def records(options = {})
1222
- context = options[:context]
1223
- current_user = context ? context[:current_user] : nil
1224
-
1225
- records = _model_class
1226
- # Hide the banned books from people who are not book admins
1227
- unless current_user && current_user.book_admin
1228
- records = records.where(not_banned_books)
1229
- end
1230
- records
1231
- end
1232
- end
1233
- end
1234
-
1235
- class BookCommentResource < JSONAPI::Resource
1236
- attributes :body, :approved
1237
-
1238
- has_one :book
1239
- has_one :author, class_name: 'Person'
1240
-
1241
- filters :book
1242
- filter :approved, apply: ->(records, value, options) {
1243
- context = options[:context]
1244
- current_user = context ? context[:current_user] : nil
1245
-
1246
- if current_user && current_user.book_admin
1247
- records.where(approved_comments(value[0] == 'true'))
1248
- end
1249
- }
1250
-
1251
- class << self
1252
- def book_comments
1253
- BookComment.arel_table
1254
- end
1255
-
1256
- def approved_comments(approved = true)
1257
- book_comments[:approved].eq(approved)
1258
- end
1259
-
1260
- def records(options = {})
1261
- current_user = options[:context][:current_user]
1262
- _model_class.for_user(current_user)
1263
- end
1264
- end
1265
- end
1266
- end
1267
- end
1268
-
1269
- module Api
1270
- module V3
1271
- class PostResource < PostResource; end
1272
- class PreferencesResource < PreferencesResource; end
1273
- end
1274
- end
1275
-
1276
- module Api
1277
- module V4
1278
- class PostResource < PostResource; end
1279
- class PersonResource < PersonResource; end
1280
- class ExpenseEntryResource < ExpenseEntryResource; end
1281
- class IsoCurrencyResource < IsoCurrencyResource; end
1282
-
1283
- class BookResource < Api::V2::BookResource
1284
- paginator :paged
1285
- end
1286
-
1287
- class BookCommentResource < Api::V2::BookCommentResource
1288
- paginator :paged
1289
- end
1290
- end
1291
- end
1292
-
1293
- module Api
1294
- module V5
1295
- class AuthorResource < JSONAPI::Resource
1296
- attributes :name, :email
1297
- model_name 'Person'
1298
- relationship :posts, to: :many
1299
- relationship :author_detail, to: :one, foreign_key_on: :related
1300
-
1301
- filter :name
1302
-
1303
- def self.find_by_key(key, options = {})
1304
- context = options[:context]
1305
- records = records(options)
1306
- records = apply_includes(records, options)
1307
- model = records.where({_primary_key => key}).first
1308
- fail JSONAPI::Exceptions::RecordNotFound.new(key) if model.nil?
1309
- self.new(model, context)
1310
- end
1311
-
1312
- def self.find(filters, options = {})
1313
- resources = []
1314
-
1315
- filters.each do |attr, filter|
1316
- _model_class.where("\"#{attr}\" LIKE \"%#{filter[0]}%\"").each do |model|
1317
- resources.push self.new(model, options[:context])
1318
- end
1319
- end
1320
- return resources
1321
- end
1322
-
1323
- def fetchable_fields
1324
- super - [:email]
1325
- end
1326
- end
1327
-
1328
- class AuthorDetailResource < JSONAPI::Resource
1329
- attributes :author_stuff
1330
- end
1331
-
1332
- class PersonResource < PersonResource; end
1333
- class PostResource < PostResource; end
1334
- class TagResource < TagResource; end
1335
- class SectionResource < SectionResource; end
1336
- class CommentResource < CommentResource; end
1337
- class ExpenseEntryResource < ExpenseEntryResource; end
1338
- class IsoCurrencyResource < IsoCurrencyResource; end
1339
- class EmployeeResource < EmployeeResource; end
1340
- end
1341
- end
1342
-
1343
- module Api
1344
- module V6
1345
- class CustomerResource < JSONAPI::Resource
1346
- attribute :name
1347
-
1348
- has_many :purchase_orders
1349
- end
1350
-
1351
- class PurchaseOrderResource < JSONAPI::Resource
1352
- attribute :order_date
1353
- attribute :requested_delivery_date
1354
- attribute :delivery_date
1355
- attribute :delivery_name
1356
- attribute :delivery_address_1
1357
- attribute :delivery_address_2
1358
- attribute :delivery_city
1359
- attribute :delivery_state
1360
- attribute :delivery_postal_code
1361
- attribute :delivery_fee
1362
- attribute :tax
1363
- attribute :total
1364
-
1365
- has_one :customer
1366
- has_many :line_items, relation_name: -> (options = {}) {
1367
- context = options[:context]
1368
- current_user = context ? context[:current_user] : nil
1369
-
1370
- unless current_user && current_user.book_admin
1371
- :line_items
1372
- else
1373
- :admin_line_items
1374
- end
1375
- }
1376
-
1377
- has_many :order_flags, acts_as_set: true,
1378
- relation_name: -> (options = {}) {
1379
- context = options[:context]
1380
- current_user = context ? context[:current_user] : nil
1381
-
1382
- unless current_user && current_user.book_admin
1383
- :order_flags
1384
- else
1385
- :admin_order_flags
1386
- end
1387
- }
1388
- end
1389
-
1390
- class OrderFlagResource < JSONAPI::Resource
1391
- attributes :name
1392
-
1393
- has_many :purchase_orders
1394
- end
1395
-
1396
- class LineItemResource < JSONAPI::Resource
1397
- attribute :part_number
1398
- attribute :quantity
1399
- attribute :item_cost
1400
-
1401
- has_one :purchase_order
1402
- end
1403
- end
1404
-
1405
- module V7
1406
- class PurchaseOrderResource < V6::PurchaseOrderResource; end
1407
- class OrderFlagResource < V6::OrderFlagResource; end
1408
- class LineItemResource < V6::LineItemResource; end
1409
-
1410
- class CustomerResource < V6::CustomerResource
1411
- model_name 'Api::V7::Customer'
1412
- attribute :name
1413
- has_many :purchase_orders
1414
- end
1415
-
1416
- class ClientResource < JSONAPI::Resource
1417
- model_name 'Api::V7::Customer'
1418
-
1419
- attribute :name
1420
-
1421
- has_many :purchase_orders
1422
- end
1423
-
1424
- class CategoryResource < CategoryResource
1425
- attribute :name
1426
-
1427
- # Raise exception for failure in controller
1428
- def name
1429
- fail "Something Exceptional Happened"
1430
- end
1431
- end
1432
- end
1433
-
1434
- module V8
1435
- class NumeroTelefoneResource < JSONAPI::Resource
1436
- attribute :numero_telefone
1437
- end
1438
- end
1439
- end
1440
-
1441
- module AdminApi
1442
- module V1
1443
- class PersonResource < JSONAPI::Resource
1444
- end
1445
- end
1446
- end
1447
-
1448
- module MyEngine
1449
- module Api
1450
- module V1
1451
- class PersonResource < JSONAPI::Resource
1452
- end
1453
- end
1454
- end
1455
-
1456
- module AdminApi
1457
- module V1
1458
- class PersonResource < JSONAPI::Resource
1459
- end
1460
- end
1461
- end
1462
- end
1463
-
1464
- module Legacy
1465
- class FlatPost < ActiveRecord::Base
1466
- self.table_name = "posts"
1467
- end
1468
- end
1469
-
1470
- class FlatPostResource < JSONAPI::Resource
1471
- model_name "Legacy::FlatPost", add_model_hint: false
1472
-
1473
- model_hint model: "Legacy::FlatPost", resource: FlatPostResource
1474
-
1475
- attribute :title
1476
- end
1477
-
1478
- class FlatPostsController < JSONAPI::ResourceController
1479
- end
1480
-
1481
- ### PORO Data - don't do this in a production app
1482
- $breed_data = BreedData.new
1483
- $breed_data.add(Breed.new(0, 'persian'))
1484
- $breed_data.add(Breed.new(1, 'siamese'))
1485
- $breed_data.add(Breed.new(2, 'sphinx'))
1486
- $breed_data.add(Breed.new(3, 'to_delete'))