Skip to content

Commit 72fb4ec

Browse files
authored
Merge pull request #955 from cerebris/model_name_rework
Rework model_name in derived resources
2 parents c1ff996 + 280ccea commit 72fb4ec

4 files changed

Lines changed: 67 additions & 43 deletions

File tree

lib/jsonapi/resource.rb

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -410,18 +410,15 @@ def inherited(subclass)
410410
subclass.immutable(false)
411411
subclass.caching(false)
412412
subclass._attributes = (_attributes || {}).dup
413+
413414
subclass._model_hints = (_model_hints || {}).dup
414415

415-
subclass._relationships = {}
416-
# Add the relationships from the base class to the subclass using the original options
417-
if _relationships.is_a?(Hash)
418-
_relationships.each_value do |relationship|
419-
options = relationship.options.dup
420-
options[:parent_resource] = subclass
421-
subclass._add_relationship(relationship.class, relationship.name, options)
422-
end
416+
unless _model_name.empty?
417+
subclass.model_name(_model_name, add_model_hint: (_model_hints && !_model_hints[_model_name].nil?) == true)
423418
end
424419

420+
subclass.rebuild_relationships(_relationships || {})
421+
425422
subclass._allowed_filters = (_allowed_filters || Set.new).dup
426423

427424
type = subclass.name.demodulize.sub(/Resource$/, '').underscore
@@ -432,6 +429,20 @@ def inherited(subclass)
432429
check_reserved_resource_name(subclass._type, subclass.name)
433430
end
434431

432+
def rebuild_relationships(relationships)
433+
original_relationships = relationships.deep_dup
434+
435+
@_relationships = {}
436+
437+
if original_relationships.is_a?(Hash)
438+
original_relationships.each_value do |relationship|
439+
options = relationship.options.dup
440+
options[:parent_resource] = self
441+
_add_relationship(relationship.class, relationship.name, options)
442+
end
443+
end
444+
end
445+
435446
def resource_for(type)
436447
type = type.underscore
437448
type_with_module = type.include?('/') ? type : module_path + type
@@ -554,6 +565,8 @@ def model_name(model, options = {})
554565
@_model_name = model.to_sym
555566

556567
model_hint(model: @_model_name, resource: self) unless options[:add_model_hint] == false
568+
569+
rebuild_relationships(_relationships)
557570
end
558571

559572
def model_hint(model: _model_name, resource: _type)
@@ -908,10 +921,11 @@ def _model_name
908921
if _abstract
909922
return ''
910923
else
911-
return @_model_name if defined?(@_model_name)
924+
return @_model_name.to_s if defined?(@_model_name)
912925
class_name = self.name
913926
return '' if class_name.nil?
914-
return @_model_name = class_name.demodulize.sub(/Resource$/, '')
927+
@_model_name = class_name.demodulize.sub(/Resource$/, '')
928+
return @_model_name.to_s
915929
end
916930
end
917931

@@ -982,11 +996,17 @@ def attribute_caching_context(context)
982996
def _model_class
983997
return nil if _abstract
984998

985-
return @model if defined?(@model)
986-
return nil if self.name.to_s.blank? && _model_name.to_s.blank?
987-
@model = _model_name.to_s.safe_constantize
988-
warn "[MODEL NOT FOUND] Model could not be found for #{self.name}. If this a base Resource declare it as abstract." if @model.nil?
989-
@model
999+
return @model_class if @model_class
1000+
1001+
model_name = _model_name
1002+
return nil if model_name.to_s.blank?
1003+
1004+
@model_class = model_name.to_s.safe_constantize
1005+
if @model_class.nil?
1006+
warn "[MODEL NOT FOUND] Model could not be found for #{self.name}. If this a base Resource declare it as abstract."
1007+
end
1008+
1009+
@model_class
9901010
end
9911011

9921012
def _allowed_filter?(filter)

test/fixtures/active_record.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,7 @@ class CompanyResource < JSONAPI::Resource
10051005
end
10061006

10071007
class FirmResource < CompanyResource
1008+
model_name "Firm"
10081009
end
10091010

10101011
class TagResource < JSONAPI::Resource

test/unit/jsonapi_request/jsonapi_request_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class CatResource < JSONAPI::Resource
44
attribute :name
55
attribute :breed
66

7-
belongs_to :mother, class_name: 'Cat'
7+
has_one :mother, class_name: 'Cat'
88
has_one :father, class_name: 'Cat'
99

1010
filters :name

test/unit/resource/resource_test.rb

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ class NoMatchAbstractResource < JSONAPI::Resource
4747
abstract
4848
end
4949

50-
class CatResource < JSONAPI::Resource
50+
class FelineResource < JSONAPI::Resource
51+
model_name 'Cat'
52+
5153
attribute :name
5254
attribute :breed
5355
attribute :kind, :delegate => :breed
@@ -99,6 +101,7 @@ class RelatedResource < MyModule::RelatedResource
99101
end
100102

101103
class PostWithReadonlyAttributesResource < JSONAPI::Resource
104+
model_name 'Post'
102105
attribute :title, readonly: true
103106
has_one :author, readonly: true
104107
end
@@ -180,7 +183,7 @@ def test_derived_not_abstract
180183
def test_nil_model_class
181184
# ToDo:Figure out why this test does not work on Rails 4.0
182185
# :nocov:
183-
if Rails::VERSION::MAJOR >= 4 && Rails::VERSION::MINOR >= 1
186+
if (Rails::VERSION::MAJOR >= 4 && Rails::VERSION::MINOR >= 1) || (Rails::VERSION::MAJOR >= 5)
184187
assert_output nil, "[MODEL NOT FOUND] Model could not be found for NoMatchResource. If this a base Resource declare it as abstract.\n" do
185188
assert_nil NoMatchResource._model_class
186189
end
@@ -199,13 +202,13 @@ def test_model_alternate
199202
end
200203

201204
def test_class_attributes
202-
attrs = CatResource._attributes
205+
attrs = FelineResource._attributes
203206
assert_kind_of(Hash, attrs)
204207
assert_equal(attrs.keys.size, 4)
205208
end
206209

207210
def test_class_relationships
208-
relationships = CatResource._relationships
211+
relationships = FelineResource._relationships
209212
assert_kind_of(Hash, relationships)
210213
assert_equal(relationships.size, 2)
211214
end
@@ -219,16 +222,16 @@ def test_replace_polymorphic_to_one_link
219222
end
220223

221224
def test_duplicate_relationship_name
222-
assert_output nil, "[DUPLICATE RELATIONSHIP] `mother` has already been defined in CatResource.\n" do
223-
CatResource.instance_eval do
225+
assert_output nil, "[DUPLICATE RELATIONSHIP] `mother` has already been defined in FelineResource.\n" do
226+
FelineResource.instance_eval do
224227
has_one :mother, class_name: 'Cat'
225228
end
226229
end
227230
end
228231

229232
def test_duplicate_attribute_name
230-
assert_output nil, "[DUPLICATE ATTRIBUTE] `name` has already been defined in CatResource.\n" do
231-
CatResource.instance_eval do
233+
assert_output nil, "[DUPLICATE ATTRIBUTE] `name` has already been defined in FelineResource.\n" do
234+
FelineResource.instance_eval do
232235
attribute :name
233236
end
234237
end
@@ -299,7 +302,7 @@ def test_find_by_key_with_customized_base_records
299302
end
300303

301304
def test_updatable_fields_does_not_include_id
302-
assert(!CatResource.updatable_fields.include?(:id))
305+
assert(!FelineResource.updatable_fields.include?(:id))
303306
end
304307

305308
def test_filter_on_to_many_relationship_id
@@ -443,60 +446,60 @@ def apply_pagination(records, criteria, order_options)
443446
end
444447

445448
def test_key_type_integer
446-
CatResource.instance_eval do
449+
FelineResource.instance_eval do
447450
key_type :integer
448451
end
449452

450-
assert CatResource.verify_key('45')
451-
assert CatResource.verify_key(45)
453+
assert FelineResource.verify_key('45')
454+
assert FelineResource.verify_key(45)
452455

453456
assert_raises JSONAPI::Exceptions::InvalidFieldValue do
454-
CatResource.verify_key('45,345')
457+
FelineResource.verify_key('45,345')
455458
end
456459

457460
ensure
458-
CatResource.instance_eval do
461+
FelineResource.instance_eval do
459462
key_type nil
460463
end
461464
end
462465

463466
def test_key_type_string
464-
CatResource.instance_eval do
467+
FelineResource.instance_eval do
465468
key_type :string
466469
end
467470

468-
assert CatResource.verify_key('45')
469-
assert CatResource.verify_key(45)
471+
assert FelineResource.verify_key('45')
472+
assert FelineResource.verify_key(45)
470473

471474
assert_raises JSONAPI::Exceptions::InvalidFieldValue do
472-
CatResource.verify_key('45,345')
475+
FelineResource.verify_key('45,345')
473476
end
474477

475478
ensure
476-
CatResource.instance_eval do
479+
FelineResource.instance_eval do
477480
key_type nil
478481
end
479482
end
480483

481484
def test_key_type_uuid
482-
CatResource.instance_eval do
485+
FelineResource.instance_eval do
483486
key_type :uuid
484487
end
485488

486-
assert CatResource.verify_key('f1a4d5f2-e77a-4d0a-acbb-ee0b98b3f6b5')
489+
assert FelineResource.verify_key('f1a4d5f2-e77a-4d0a-acbb-ee0b98b3f6b5')
487490

488491
assert_raises JSONAPI::Exceptions::InvalidFieldValue do
489-
CatResource.verify_key('f1a-e77a-4d0a-acbb-ee0b98b3f6b5')
492+
FelineResource.verify_key('f1a-e77a-4d0a-acbb-ee0b98b3f6b5')
490493
end
491494

492495
ensure
493-
CatResource.instance_eval do
496+
FelineResource.instance_eval do
494497
key_type nil
495498
end
496499
end
497500

498501
def test_key_type_proc
499-
CatResource.instance_eval do
502+
FelineResource.instance_eval do
500503
key_type -> (key, context) {
501504
return key if key.nil?
502505
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}$/)
@@ -507,14 +510,14 @@ def test_key_type_proc
507510
}
508511
end
509512

510-
assert CatResource.verify_key('f1a4d5f2-e77a-4d0a-acbb-ee0b98b3f6b5')
513+
assert FelineResource.verify_key('f1a4d5f2-e77a-4d0a-acbb-ee0b98b3f6b5')
511514

512515
assert_raises JSONAPI::Exceptions::InvalidFieldValue do
513-
CatResource.verify_key('f1a-e77a-4d0a-acbb-ee0b98b3f6b5')
516+
FelineResource.verify_key('f1a-e77a-4d0a-acbb-ee0b98b3f6b5')
514517
end
515518

516519
ensure
517-
CatResource.instance_eval do
520+
FelineResource.instance_eval do
518521
key_type nil
519522
end
520523
end

0 commit comments

Comments
 (0)