@@ -39,7 +39,7 @@ def _model
3939 end
4040
4141 def id
42- _model . public_send ( self . class . _primary_key )
42+ @id ||= _model . public_send ( self . class . _primary_key )
4343 end
4444
4545 def identity
@@ -510,7 +510,10 @@ def inherited(subclass)
510510 subclass . _routed = false
511511 subclass . _warned_missing_route = false
512512
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+
514517 subclass . _clear_fields_cache
515518
516519 subclass . _resource_retrieval_strategy_loaded = @_resource_retrieval_strategy_loaded
@@ -533,15 +536,19 @@ def rebuild_relationships(relationships)
533536 end
534537
535538 def resource_klass_for ( type )
539+ @_resource_type_to_class_cache ||= { }
536540 type = type . underscore
537- type_with_module = type . start_with? ( module_path ) ? type : module_path + type
538541
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
543551 end
544- resource
545552 end
546553
547554 def resource_klass_for_model ( model )
@@ -553,17 +560,33 @@ def _resource_name_from_type(type)
553560 end
554561
555562 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
561573 end
562574 end
563575
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 ,
565582 :_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
567590
568591 def create ( context )
569592 new ( create_model , context )
@@ -590,7 +613,7 @@ def attributes(*attrs)
590613 end
591614
592615 def attribute ( attribute_name , options = { } )
593- _clear_cached_attribute_options
616+ _clear_attribute_options_cache
594617 _clear_fields_cache
595618
596619 attr = attribute_name . to_sym
@@ -903,7 +926,7 @@ def verify_relationship_filter(filter, raw, _context = nil)
903926
904927 # quasi private class methods
905928 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 ] )
907930 end
908931
909932 def _attribute_delegated_name ( attr )
@@ -915,11 +938,11 @@ def _has_attribute?(attr)
915938 end
916939
917940 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? }
919942 end
920943
921944 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? }
923946 end
924947
925948 def _relationship ( type )
@@ -1132,11 +1155,11 @@ def _has_sort?(sorting)
11321155 end
11331156
11341157 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
11401163 end
11411164
11421165 def default_sort
@@ -1169,18 +1192,6 @@ def _add_relationship(klass, *attrs)
11691192 end
11701193 end
11711194
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-
11841195 # ResourceBuilder methods
11851196 def define_relationship_methods ( relationship_name , relationship_klass , options )
11861197 relationship = register_relationship (
@@ -1214,8 +1225,16 @@ def register_relationship(name, relationship_object)
12141225 @_relationships [ name ] = relationship_object
12151226 end
12161227
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
12191238 end
12201239
12211240 def _clear_fields_cache
0 commit comments