@@ -39,7 +39,7 @@ def _model
39
39
end
40
40
41
41
def id
42
- _model . public_send ( self . class . _primary_key )
42
+ @id ||= _model . public_send ( self . class . _primary_key )
43
43
end
44
44
45
45
def identity
@@ -510,7 +510,10 @@ def inherited(subclass)
510
510
subclass . _routed = false
511
511
subclass . _warned_missing_route = false
512
512
513
- subclass . _clear_cached_attribute_options
513
+ subclass . _attribute_options_cache = { }
514
+ subclass . _model_class_to_resource_type_cache = { }
515
+ subclass . _resource_type_to_class_cache = { }
516
+
514
517
subclass . _clear_fields_cache
515
518
516
519
subclass . _resource_retrieval_strategy_loaded = @_resource_retrieval_strategy_loaded
@@ -533,15 +536,19 @@ def rebuild_relationships(relationships)
533
536
end
534
537
535
538
def resource_klass_for ( type )
539
+ @_resource_type_to_class_cache ||= { }
536
540
type = type . underscore
537
- type_with_module = type . start_with? ( module_path ) ? type : module_path + type
538
541
539
- resource_name = _resource_name_from_type ( type_with_module )
540
- resource = resource_name . safe_constantize if resource_name
541
- if resource . nil?
542
- fail NameError , "JSONAPI: Could not find resource '#{ type } '. (Class #{ resource_name } not found)"
542
+ @_resource_type_to_class_cache . fetch ( type ) do
543
+ type_with_module = type . start_with? ( module_path ) ? type : module_path + type
544
+
545
+ resource_name = _resource_name_from_type ( type_with_module )
546
+ resource_klass = resource_name . safe_constantize if resource_name
547
+ if resource_klass . nil?
548
+ fail NameError , "JSONAPI: Could not find resource '#{ type } '. (Class #{ resource_name } not found)"
549
+ end
550
+ @_resource_type_to_class_cache [ type ] = resource_klass
543
551
end
544
- resource
545
552
end
546
553
547
554
def resource_klass_for_model ( model )
@@ -553,17 +560,33 @@ def _resource_name_from_type(type)
553
560
end
554
561
555
562
def resource_type_for ( model )
556
- model_name = model . class . to_s . underscore
557
- if _model_hints [ model_name ]
558
- _model_hints [ model_name ]
559
- else
560
- model_name . rpartition ( '/' ) . last
563
+ @_model_class_to_resource_type_cache . fetch ( model . class ) do
564
+ model_name = model . class . name . underscore
565
+
566
+ resource_type = if _model_hints [ model_name ]
567
+ _model_hints [ model_name ]
568
+ else
569
+ model_name . rpartition ( '/' ) . last
570
+ end
571
+
572
+ @_model_class_to_resource_type_cache [ model . class ] = resource_type
561
573
end
562
574
end
563
575
564
- attr_accessor :_attributes , :_relationships , :_type , :_model_hints , :_routed , :_warned_missing_route ,
576
+ attr_accessor :_attributes ,
577
+ :_relationships ,
578
+ :_type ,
579
+ :_model_hints ,
580
+ :_routed ,
581
+ :_warned_missing_route ,
565
582
:_resource_retrieval_strategy_loaded
566
- attr_writer :_allowed_filters , :_paginator , :_allowed_sort
583
+
584
+ attr_writer :_allowed_filters ,
585
+ :_paginator ,
586
+ :_allowed_sort ,
587
+ :_model_class_to_resource_type_cache ,
588
+ :_resource_type_to_class_cache ,
589
+ :_attribute_options_cache
567
590
568
591
def create ( context )
569
592
new ( create_model , context )
@@ -590,7 +613,7 @@ def attributes(*attrs)
590
613
end
591
614
592
615
def attribute ( attribute_name , options = { } )
593
- _clear_cached_attribute_options
616
+ _clear_attribute_options_cache
594
617
_clear_fields_cache
595
618
596
619
attr = attribute_name . to_sym
@@ -903,7 +926,7 @@ def verify_relationship_filter(filter, raw, _context = nil)
903
926
904
927
# quasi private class methods
905
928
def _attribute_options ( attr )
906
- @_cached_attribute_options [ attr ] ||= default_attribute_options . merge ( @_attributes [ attr ] )
929
+ @_attribute_options_cache [ attr ] ||= default_attribute_options . merge ( @_attributes [ attr ] )
907
930
end
908
931
909
932
def _attribute_delegated_name ( attr )
@@ -915,11 +938,11 @@ def _has_attribute?(attr)
915
938
end
916
939
917
940
def _updatable_attributes
918
- _attributes . map { |key , options | key unless options [ :readonly ] } . compact
941
+ _attributes . map { |key , options | key unless options [ :readonly ] } . delete_if { | v | v . nil? }
919
942
end
920
943
921
944
def _updatable_relationships
922
- @_relationships . map { |key , relationship | key unless relationship . readonly? } . compact
945
+ @_relationships . map { |key , relationship | key unless relationship . readonly? } . delete_if { | v | v . nil? }
923
946
end
924
947
925
948
def _relationship ( type )
@@ -1132,11 +1155,11 @@ def _has_sort?(sorting)
1132
1155
end
1133
1156
1134
1157
def module_path
1135
- if name == 'JSONAPI::Resource'
1136
- ''
1137
- else
1138
- name =~ /::[^:]+\Z / ? ( $`. freeze . gsub ( '::' , '/' ) + '/' ) . underscore : ''
1139
- end
1158
+ @module_path ||= if name == 'JSONAPI::Resource'
1159
+ ''
1160
+ else
1161
+ name =~ /::[^:]+\Z / ? ( $`. freeze . gsub ( '::' , '/' ) + '/' ) . underscore : ''
1162
+ end
1140
1163
end
1141
1164
1142
1165
def default_sort
@@ -1169,18 +1192,6 @@ def _add_relationship(klass, *attrs)
1169
1192
end
1170
1193
end
1171
1194
1172
- def _setup_relationship ( klass , *attrs )
1173
- _clear_fields_cache
1174
-
1175
- options = attrs . extract_options!
1176
- options [ :parent_resource ] = self
1177
-
1178
- relationship_name = attrs [ 0 ] . to_sym
1179
- check_duplicate_relationship_name ( relationship_name )
1180
-
1181
- define_relationship_methods ( relationship_name . to_sym , klass , options )
1182
- end
1183
-
1184
1195
# ResourceBuilder methods
1185
1196
def define_relationship_methods ( relationship_name , relationship_klass , options )
1186
1197
relationship = register_relationship (
@@ -1214,8 +1225,16 @@ def register_relationship(name, relationship_object)
1214
1225
@_relationships [ name ] = relationship_object
1215
1226
end
1216
1227
1217
- def _clear_cached_attribute_options
1218
- @_cached_attribute_options = { }
1228
+ def _clear_attribute_options_cache
1229
+ @_attribute_options_cache &.clear
1230
+ end
1231
+
1232
+ def _clear_model_to_resource_type_cache
1233
+ @_model_class_to_resource_type_cache &.clear
1234
+ end
1235
+
1236
+ def _clear_resource_type_to_klass_cache
1237
+ @_resource_type_to_class_cache &.clear
1219
1238
end
1220
1239
1221
1240
def _clear_fields_cache
0 commit comments