jsonapi-resources 0.6.2 → 0.7.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.
@@ -1,7 +1,7 @@
1
1
  module JSONAPI
2
2
  class ResourceSerializer
3
3
 
4
- attr_reader :url_generator, :key_formatter, :serialization_options, :primary_class_name
4
+ attr_reader :link_builder, :key_formatter, :serialization_options, :primary_class_name
5
5
 
6
6
  # initialize
7
7
  # Options can include
@@ -21,7 +21,7 @@ module JSONAPI
21
21
  @include = options.fetch(:include, [])
22
22
  @include_directives = options[:include_directives]
23
23
  @key_formatter = options.fetch(:key_formatter, JSONAPI.configuration.key_formatter)
24
- @url_generator = generate_link_builder(primary_resource_klass, options)
24
+ @link_builder = generate_link_builder(primary_resource_klass, options)
25
25
  @always_include_to_one_linkage_data = options.fetch(:always_include_to_one_linkage_data,
26
26
  JSONAPI.configuration.always_include_to_one_linkage_data)
27
27
  @always_include_to_many_linkage_data = options.fetch(:always_include_to_many_linkage_data,
@@ -72,8 +72,8 @@ module JSONAPI
72
72
  }
73
73
  end
74
74
 
75
- def find_link(query_params)
76
- url_generator.query_link(query_params)
75
+ def query_link(query_params)
76
+ link_builder.query_link(query_params)
77
77
  end
78
78
 
79
79
  def format_key(key)
@@ -226,7 +226,7 @@ module JSONAPI
226
226
 
227
227
  def relationship_links(source)
228
228
  links = {}
229
- links[:self] = url_generator.self_link(source)
229
+ links[:self] = link_builder.self_link(source)
230
230
 
231
231
  links
232
232
  end
@@ -237,11 +237,11 @@ module JSONAPI
237
237
  end
238
238
 
239
239
  def self_link(source, relationship)
240
- url_generator.relationships_self_link(source, relationship)
240
+ link_builder.relationships_self_link(source, relationship)
241
241
  end
242
242
 
243
243
  def related_link(source, relationship)
244
- url_generator.relationships_related_link(source, relationship)
244
+ link_builder.relationships_related_link(source, relationship)
245
245
  end
246
246
 
247
247
  def to_one_linkage(source, relationship)
@@ -1,5 +1,5 @@
1
1
  module JSONAPI
2
2
  module Resources
3
- VERSION = '0.6.2'
3
+ VERSION = '0.7.0'
4
4
  end
5
5
  end
@@ -74,9 +74,9 @@ module JSONAPI
74
74
  result.pagination_params.each_pair do |link_name, params|
75
75
  if result.is_a?(JSONAPI::RelatedResourcesOperationResult)
76
76
  relationship = result.source_resource.class._relationships[result._type.to_sym]
77
- links[link_name] = serializer.url_generator.relationships_related_link(result.source_resource, relationship, query_params(params))
77
+ links[link_name] = serializer.link_builder.relationships_related_link(result.source_resource, relationship, query_params(params))
78
78
  else
79
- links[link_name] = serializer.find_link(query_params(params))
79
+ links[link_name] = serializer.query_link(query_params(params))
80
80
  end
81
81
  end
82
82
  end
@@ -2183,7 +2183,7 @@ class PeopleControllerTest < ActionController::TestCase
2183
2183
  assert_equal json_response['data'][0]['attributes']['name'], 'Joe Author'
2184
2184
  end
2185
2185
 
2186
- def test_get_related_resource
2186
+ def test_get_related_resource_no_namespace
2187
2187
  original_config = JSONAPI.configuration.dup
2188
2188
  JSONAPI.configuration.json_key_format = :dasherized_key
2189
2189
  JSONAPI.configuration.route_format = :underscored_key
@@ -2253,6 +2253,15 @@ class PeopleControllerTest < ActionController::TestCase
2253
2253
  end
2254
2254
  end
2255
2255
 
2256
+ class BooksControllerTest < ActionController::TestCase
2257
+ def test_books_include_correct_type
2258
+ $test_user = Person.find(1)
2259
+ get :index, {filter: {id: '1'}, include: 'authors'}
2260
+ assert_response :success
2261
+ assert_equal 'authors', json_response['included'][0]['type']
2262
+ end
2263
+ end
2264
+
2256
2265
  class Api::V5::AuthorsControllerTest < ActionController::TestCase
2257
2266
  def test_get_person_as_author
2258
2267
  get :index, {filter: {id: '1'}}
@@ -2288,7 +2297,7 @@ class Api::V5::AuthorsControllerTest < ActionController::TestCase
2288
2297
  def meta(options)
2289
2298
  {
2290
2299
  fixed: 'Hardcoded value',
2291
- computed: "#{self.class._type.to_s}: #{options[:serializer].url_generator.self_link(self)}",
2300
+ computed: "#{self.class._type.to_s}: #{options[:serializer].link_builder.self_link(self)}",
2292
2301
  computed_foo: options[:serialization_options][:foo],
2293
2302
  options[:serializer].format_key('test_key') => 'test value'
2294
2303
  }
@@ -2322,7 +2331,7 @@ class Api::V5::AuthorsControllerTest < ActionController::TestCase
2322
2331
  {
2323
2332
  custom_hash: {
2324
2333
  fixed: 'Hardcoded value',
2325
- computed: "#{self.class._type.to_s}: #{options[:serializer].url_generator.self_link(self)}",
2334
+ computed: "#{self.class._type.to_s}: #{options[:serializer].link_builder.self_link(self)}",
2326
2335
  computed_foo: options[:serialization_options][:foo],
2327
2336
  options[:serializer].format_key('test_key') => 'test value'
2328
2337
  }
@@ -3100,19 +3109,17 @@ class Api::V1::MoonsControllerTest < ActionController::TestCase
3100
3109
  def test_get_related_resource
3101
3110
  get :get_related_resource, {crater_id: 'S56D', relationship: 'moon', source: "api/v1/craters"}
3102
3111
  assert_response :success
3103
- assert_hash_equals json_response,
3104
- {
3105
- data: {
3106
- id: "1",
3107
- type: "moons",
3108
- links: {self: "http://test.host/moons/1"},
3109
- attributes: {name: "Titan", description: "Best known of the Saturn moons."},
3110
- relationships: {
3111
- planet: {links: {self: "http://test.host/moons/1/relationships/planet", related: "http://test.host/moons/1/planet"}},
3112
- craters: {links: {self: "http://test.host/moons/1/relationships/craters", related: "http://test.host/moons/1/craters"}}}
3113
- }
3114
- }
3115
-
3112
+ assert_hash_equals({
3113
+ data: {
3114
+ id: "1",
3115
+ type: "moons",
3116
+ links: {self: "http://test.host/api/v1/moons/1"},
3117
+ attributes: {name: "Titan", description: "Best known of the Saturn moons."},
3118
+ relationships: {
3119
+ planet: {links: {self: "http://test.host/api/v1/moons/1/relationships/planet", related: "http://test.host/api/v1/moons/1/planet"}},
3120
+ craters: {links: {self: "http://test.host/api/v1/moons/1/relationships/craters", related: "http://test.host/api/v1/moons/1/craters"}}}
3121
+ }
3122
+ }, json_response)
3116
3123
  end
3117
3124
 
3118
3125
  def test_get_related_resources_with_select_some_db_columns
@@ -3141,23 +3148,24 @@ class Api::V1::CratersControllerTest < ActionController::TestCase
3141
3148
  def test_get_related_resources
3142
3149
  get :get_related_resources, {moon_id: '1', relationship: 'craters', source: "api/v1/moons"}
3143
3150
  assert_response :success
3144
- assert_hash_equals json_response,
3145
- {
3146
- data: [
3147
- {id:"A4D3",
3148
- type:"craters",
3149
- links:{self: "http://test.host/api/v1/craters/A4D3"},
3150
- attributes:{code: "A4D3", description: "Small crater"},
3151
- relationships:{moon: {links: {self: "http://test.host/api/v1/craters/A4D3/relationships/moon", related: "http://test.host/api/v1/craters/A4D3/moon"}}}
3152
- },
3153
- {id: "S56D",
3154
- type: "craters",
3155
- links:{self: "http://test.host/api/v1/craters/S56D"},
3156
- attributes:{code: "S56D", description: "Very large crater"},
3157
- relationships:{moon: {links: {self: "http://test.host/api/v1/craters/S56D/relationships/moon", related: "http://test.host/api/v1/craters/S56D/moon"}}}
3158
- }
3159
- ]
3160
- }
3151
+ assert_hash_equals({
3152
+ data: [
3153
+ {
3154
+ id:"A4D3",
3155
+ type:"craters",
3156
+ links:{self: "http://test.host/api/v1/craters/A4D3"},
3157
+ attributes:{code: "A4D3", description: "Small crater"},
3158
+ relationships:{moon: {links: {self: "http://test.host/api/v1/craters/A4D3/relationships/moon", related: "http://test.host/api/v1/craters/A4D3/moon"}}}
3159
+ },
3160
+ {
3161
+ id: "S56D",
3162
+ type: "craters",
3163
+ links:{self: "http://test.host/api/v1/craters/S56D"},
3164
+ attributes:{code: "S56D", description: "Very large crater"},
3165
+ relationships:{moon: {links: {self: "http://test.host/api/v1/craters/S56D/relationships/moon", related: "http://test.host/api/v1/craters/S56D/moon"}}}
3166
+ }
3167
+ ]
3168
+ }, json_response)
3161
3169
  end
3162
3170
 
3163
3171
  def test_show_relationship
@@ -3236,3 +3244,39 @@ class VehiclesControllerTest < ActionController::TestCase
3236
3244
  end
3237
3245
  end
3238
3246
  end
3247
+
3248
+ class Api::V7::ClientsControllerTest < ActionController::TestCase
3249
+ def test_get_namespaced_model_not_matching_resource_using_model_hint
3250
+ get :index
3251
+ assert_response :success
3252
+ assert_equal 'clients', json_response['data'][0]['type']
3253
+ ensure
3254
+ Api::V7::ClientResource._model_hints['api/v7/customer'] = 'clients'
3255
+ end
3256
+
3257
+ def test_get_namespaced_model_not_matching_resource_not_using_model_hint
3258
+ Api::V7::ClientResource._model_hints.delete('api/v7/customer')
3259
+ get :index
3260
+ assert_response :success
3261
+ assert_equal 'customers', json_response['data'][0]['type']
3262
+ ensure
3263
+ Api::V7::ClientResource._model_hints['api/v7/customer'] = 'clients'
3264
+ end
3265
+ end
3266
+
3267
+ class Api::V7::CustomersControllerTest < ActionController::TestCase
3268
+ def test_get_namespaced_model_matching_resource
3269
+ get :index
3270
+ assert_response :success
3271
+ assert_equal 'customers', json_response['data'][0]['type']
3272
+ end
3273
+ end
3274
+
3275
+ class Api::V7::CategoriesControllerTest < ActionController::TestCase
3276
+ def test_uncaught_error_in_controller
3277
+
3278
+ get :show, {id: '1'}
3279
+ assert_response 500
3280
+ assert_match /Internal Server Error/, json_response['errors'][0]['detail']
3281
+ end
3282
+ end
@@ -15,6 +15,7 @@ ActiveRecord::Schema.define do
15
15
  t.belongs_to :preferences
16
16
  t.integer :hair_cut_id, index: true
17
17
  t.boolean :book_admin, default: false
18
+ t.boolean :special, default: false
18
19
  t.timestamps null: false
19
20
  end
20
21
 
@@ -134,6 +135,11 @@ ActiveRecord::Schema.define do
134
135
  t.boolean :banned, default: false
135
136
  end
136
137
 
138
+ create_table :book_authors, force: true do |t|
139
+ t.integer :book_id
140
+ t.integer :person_id
141
+ end
142
+
137
143
  create_table :book_comments, force: true do |t|
138
144
  t.text :body
139
145
  t.belongs_to :book, index: true
@@ -254,6 +260,8 @@ class Person < ActiveRecord::Base
254
260
  belongs_to :hair_cut
255
261
  has_one :author_detail
256
262
 
263
+ has_and_belongs_to_many :books, join_table: :book_authors
264
+
257
265
  ### Validations
258
266
  validates :name, presence: true
259
267
  validates :date_joined, presence: true
@@ -408,6 +416,8 @@ end
408
416
  class Book < ActiveRecord::Base
409
417
  has_many :book_comments
410
418
  has_many :approved_book_comments, -> { where(approved: true) }, class_name: "BookComment"
419
+
420
+ has_and_belongs_to_many :authors, join_table: :book_authors, class_name: "Person"
411
421
  end
412
422
 
413
423
  class BookComment < ActiveRecord::Base
@@ -502,6 +512,16 @@ end
502
512
  class WebPage < ActiveRecord::Base
503
513
  end
504
514
 
515
+ module Api
516
+ module V7
517
+ class Client < Customer
518
+ end
519
+
520
+ class Customer < Customer
521
+ end
522
+ end
523
+ end
524
+
505
525
  ### OperationsProcessor
506
526
  class CountingActiveRecordOperationsProcessor < ActiveRecordOperationsProcessor
507
527
  after_find_operation do
@@ -545,6 +565,15 @@ class PostsController < BaseController
545
565
  head :forbidden
546
566
  end
547
567
 
568
+ def handle_exceptions(e)
569
+ case e
570
+ when PostsController::SpecialError
571
+ raise e
572
+ else
573
+ super(e)
574
+ end
575
+ end
576
+
548
577
  #called by test_on_server_error
549
578
  def self.set_callback_message(error)
550
579
  @callback_message = "Sent from method"
@@ -599,6 +628,12 @@ end
599
628
  class BoatsController < JSONAPI::ResourceController
600
629
  end
601
630
 
631
+ class BooksController < JSONAPI::ResourceController
632
+ end
633
+
634
+ class AuthorsController < JSONAPI::ResourceController
635
+ end
636
+
602
637
  ### CONTROLLERS
603
638
  module Api
604
639
  module V1
@@ -731,6 +766,12 @@ module Api
731
766
 
732
767
  class OrderFlagsController < JSONAPI::ResourceController
733
768
  end
769
+
770
+ class CategoriesController < JSONAPI::ResourceController
771
+ end
772
+
773
+ class ClientsController < JSONAPI::ResourceController
774
+ end
734
775
  end
735
776
 
736
777
  module V8
@@ -755,18 +796,27 @@ class PersonResource < BaseResource
755
796
  has_one :preferences
756
797
  has_one :hair_cut
757
798
 
758
- filter :name
759
-
760
- def self.verify_custom_filter(filter, values, context)
761
- case filter
762
- when :name
763
- values.each do |value|
764
- if value.length < 3
765
- raise JSONAPI::Exceptions::InvalidFilterValue.new(filter, value)
766
- end
767
- end
799
+ filter :name, verify: ->(values, _context) {
800
+ values.each do |value|
801
+ if value.length < 3
802
+ raise JSONAPI::Exceptions::InvalidFilterValue.new(:name, value)
803
+ end
768
804
  end
769
- return filter, values
805
+ return values
806
+ }
807
+ end
808
+
809
+ class SpecialBaseResource < BaseResource
810
+ abstract
811
+
812
+ model_hint model: Person, resource: :special_person
813
+ end
814
+
815
+ class SpecialPersonResource < SpecialBaseResource
816
+ model_name 'Person'
817
+
818
+ def self.records(options = {})
819
+ Person.where(special: true)
770
820
  end
771
821
  end
772
822
 
@@ -871,7 +921,18 @@ class PostResource < JSONAPI::Resource
871
921
  end
872
922
 
873
923
  filters :title, :author, :tags, :comments
874
- filters :id, :ids
924
+ filter :id, verify: ->(values, context) {
925
+ verify_keys(values, context)
926
+ return values
927
+ }
928
+ filter :ids,
929
+ verify: ->(values, context) {
930
+ verify_keys(values, context)
931
+ return values
932
+ },
933
+ apply: -> (records, value, _options) {
934
+ records.where('id IN (?)', value)
935
+ }
875
936
 
876
937
  def self.updatable_fields(context)
877
938
  super(context) - [:author, :subject]
@@ -885,17 +946,6 @@ class PostResource < JSONAPI::Resource
885
946
  super(context) - [:id]
886
947
  end
887
948
 
888
- def self.verify_custom_filter(filter, values, context = nil)
889
- case filter
890
- when :id
891
- verify_keys(values, context)
892
- when :ids #coerce :ids to :id
893
- verify_keys(values, context)
894
- return :id, values
895
- end
896
- return filter, values
897
- end
898
-
899
949
  def self.verify_key(key, context = nil)
900
950
  super(key)
901
951
  raise JSONAPI::Exceptions::RecordNotFound.new(key) unless find_by_key(key, context: context)
@@ -1058,6 +1108,19 @@ class WebPageResource < JSONAPI::Resource
1058
1108
  attribute :link
1059
1109
  end
1060
1110
 
1111
+ class AuthorResource < JSONAPI::Resource
1112
+ model_name 'Person'
1113
+ attributes :name
1114
+ end
1115
+
1116
+ class BookResource < JSONAPI::Resource
1117
+ has_many :authors, class_name: 'Author'
1118
+ end
1119
+
1120
+ class AuthorDetailResource < JSONAPI::Resource
1121
+ attributes :author_stuff
1122
+ end
1123
+
1061
1124
  module Api
1062
1125
  module V1
1063
1126
  class WriterResource < JSONAPI::Resource
@@ -1088,32 +1151,32 @@ module Api
1088
1151
  filters :writer
1089
1152
  end
1090
1153
 
1091
- PersonResource = PersonResource.dup
1092
- CommentResource = CommentResource.dup
1093
- TagResource = TagResource.dup
1094
- SectionResource = SectionResource.dup
1095
- IsoCurrencyResource = IsoCurrencyResource.dup
1096
- ExpenseEntryResource = ExpenseEntryResource.dup
1097
- BreedResource = BreedResource.dup
1098
- PlanetResource = PlanetResource.dup
1099
- PlanetTypeResource = PlanetTypeResource.dup
1100
- MoonResource = MoonResource.dup
1101
- CraterResource = CraterResource.dup
1102
- PreferencesResource = PreferencesResource.dup
1103
- EmployeeResource = EmployeeResource.dup
1104
- FriendResource = FriendResource.dup
1105
- HairCutResource = HairCutResource.dup
1106
- VehicleResource = VehicleResource.dup
1107
- CarResource = CarResource.dup
1108
- BoatResource = BoatResource.dup
1154
+ class PersonResource < PersonResource; end
1155
+ class CommentResource < CommentResource; end
1156
+ class TagResource < TagResource; end
1157
+ class SectionResource < SectionResource; end
1158
+ class IsoCurrencyResource < IsoCurrencyResource; end
1159
+ class ExpenseEntryResource < ExpenseEntryResource; end
1160
+ class BreedResource < BreedResource; end
1161
+ class PlanetResource < PlanetResource; end
1162
+ class PlanetTypeResource < PlanetTypeResource; end
1163
+ class MoonResource < MoonResource; end
1164
+ class CraterResource < CraterResource; end
1165
+ class PreferencesResource < PreferencesResource; end
1166
+ class EmployeeResource < EmployeeResource; end
1167
+ class FriendResource < FriendResource; end
1168
+ class HairCutResource < HairCutResource; end
1169
+ class VehicleResource < VehicleResource; end
1170
+ class CarResource < CarResource; end
1171
+ class BoatResource < BoatResource; end
1109
1172
  end
1110
1173
  end
1111
1174
 
1112
1175
  module Api
1113
1176
  module V2
1114
- PreferencesResource = PreferencesResource.dup
1115
- PersonResource = PersonResource.dup
1116
- PostResource = PostResource.dup
1177
+ class PreferencesResource < PreferencesResource; end
1178
+ class PersonResource < PersonResource; end
1179
+ class PostResource < PostResource; end
1117
1180
 
1118
1181
  class BookResource < JSONAPI::Resource
1119
1182
  attribute :title
@@ -1132,24 +1195,18 @@ module Api
1132
1195
 
1133
1196
  has_many :aliased_comments, class_name: 'BookComments', relation_name: :approved_book_comments
1134
1197
 
1135
- filters :banned, :book_comments
1136
-
1137
- class << self
1138
- def apply_filter(records, filter, value, options)
1139
- context = options[:context]
1140
- current_user = context ? context[:current_user] : nil
1198
+ filters :book_comments
1199
+ filter :banned, apply: ->(records, value, options) {
1200
+ context = options[:context]
1201
+ current_user = context ? context[:current_user] : nil
1141
1202
 
1142
- case filter
1143
- when :banned
1144
- # Only book admins my filter for banned books
1145
- if current_user && current_user.book_admin
1146
- return records.where('books.banned = ?', value[0] == 'true')
1147
- end
1148
- else
1149
- return super(records, filter, value)
1150
- end
1203
+ # Only book admins my filter for banned books
1204
+ if current_user && current_user.book_admin
1205
+ records.where('books.banned = ?', value[0] == 'true')
1151
1206
  end
1207
+ }
1152
1208
 
1209
+ class << self
1153
1210
  def books
1154
1211
  Book.arel_table
1155
1212
  end
@@ -1178,7 +1235,15 @@ module Api
1178
1235
  has_one :book
1179
1236
  has_one :author, class_name: 'Person'
1180
1237
 
1181
- filters :approved, :book
1238
+ filters :book
1239
+ filter :approved, apply: ->(records, value, options) {
1240
+ context = options[:context]
1241
+ current_user = context ? context[:current_user] : nil
1242
+
1243
+ if current_user && current_user.book_admin
1244
+ records.where(approved_comments(value[0] == 'true'))
1245
+ end
1246
+ }
1182
1247
 
1183
1248
  class << self
1184
1249
  def book_comments
@@ -1189,23 +1254,6 @@ module Api
1189
1254
  book_comments[:approved].eq(approved)
1190
1255
  end
1191
1256
 
1192
- def apply_filter(records, filter, value, options)
1193
- context = options[:context]
1194
- current_user = context ? context[:current_user] : nil
1195
-
1196
- case filter
1197
- when :approved
1198
- # Only book admins my filter for unapproved comments
1199
- if current_user && current_user.book_admin
1200
- records.where(approved_comments(value[0] == 'true'))
1201
- end
1202
- else
1203
- #:nocov:
1204
- return super(records, filter, value)
1205
- #:nocov:
1206
- end
1207
- end
1208
-
1209
1257
  def records(options = {})
1210
1258
  current_user = options[:context][:current_user]
1211
1259
  _model_class.for_user(current_user)
@@ -1217,17 +1265,17 @@ end
1217
1265
 
1218
1266
  module Api
1219
1267
  module V3
1220
- PostResource = PostResource.dup
1221
- PreferencesResource = PreferencesResource.dup
1268
+ class PostResource < PostResource; end
1269
+ class PreferencesResource < PreferencesResource; end
1222
1270
  end
1223
1271
  end
1224
1272
 
1225
1273
  module Api
1226
1274
  module V4
1227
- PostResource = PostResource.dup
1228
- ExpenseEntryResource = ExpenseEntryResource.dup
1229
- IsoCurrencyResource = IsoCurrencyResource.dup
1230
-
1275
+ class PostResource < PostResource; end
1276
+ class PersonResource < PersonResource; end
1277
+ class ExpenseEntryResource < ExpenseEntryResource; end
1278
+ class IsoCurrencyResource < IsoCurrencyResource; end
1231
1279
 
1232
1280
  class BookResource < Api::V2::BookResource
1233
1281
  paginator :paged
@@ -1278,11 +1326,14 @@ module Api
1278
1326
  attributes :author_stuff
1279
1327
  end
1280
1328
 
1281
- PersonResource = PersonResource.dup
1282
- PostResource = PostResource.dup
1283
- ExpenseEntryResource = ExpenseEntryResource.dup
1284
- IsoCurrencyResource = IsoCurrencyResource.dup
1285
- EmployeeResource = EmployeeResource.dup
1329
+ class PersonResource < PersonResource; end
1330
+ class PostResource < PostResource; end
1331
+ class TagResource < TagResource; end
1332
+ class SectionResource < SectionResource; end
1333
+ class CommentResource < CommentResource; end
1334
+ class ExpenseEntryResource < ExpenseEntryResource; end
1335
+ class IsoCurrencyResource < IsoCurrencyResource; end
1336
+ class EmployeeResource < EmployeeResource; end
1286
1337
  end
1287
1338
  end
1288
1339
 
@@ -1349,10 +1400,32 @@ module Api
1349
1400
  end
1350
1401
 
1351
1402
  module V7
1352
- CustomerResource = V6::CustomerResource.dup
1353
- PurchaseOrderResource = V6::PurchaseOrderResource.dup
1354
- OrderFlagResource = V6::OrderFlagResource.dup
1355
- LineItemResource = V6::LineItemResource.dup
1403
+ class PurchaseOrderResource < V6::PurchaseOrderResource; end
1404
+ class OrderFlagResource < V6::OrderFlagResource; end
1405
+ class LineItemResource < V6::LineItemResource; end
1406
+
1407
+ class CustomerResource < V6::CustomerResource
1408
+ model_name 'Api::V7::Customer'
1409
+ attribute :name
1410
+ has_many :purchase_orders
1411
+ end
1412
+
1413
+ class ClientResource < JSONAPI::Resource
1414
+ model_name 'Api::V7::Customer'
1415
+
1416
+ attribute :name
1417
+
1418
+ has_many :purchase_orders
1419
+ end
1420
+
1421
+ class CategoryResource < CategoryResource
1422
+ attribute :name
1423
+
1424
+ # Raise exception for failure in controller
1425
+ def name
1426
+ fail "Something Exceptional Happened"
1427
+ end
1428
+ end
1356
1429
  end
1357
1430
 
1358
1431
  module V8
@@ -1392,7 +1465,10 @@ module Legacy
1392
1465
  end
1393
1466
 
1394
1467
  class FlatPostResource < JSONAPI::Resource
1395
- model_name "::Legacy::FlatPost"
1468
+ model_name "Legacy::FlatPost", add_model_hint: false
1469
+
1470
+ model_hint model: "Legacy::FlatPost", resource: FlatPostResource
1471
+
1396
1472
  attribute :title
1397
1473
  end
1398
1474