@@ -421,75 +421,21 @@ def inherited(subclass)
421421 subclass . attribute :id , format : :id , readonly : true
422422 end
423423
424- check_reserved_resource_name ( subclass . _type , subclass . name )
425-
426- subclass . include JSONAPI . configuration . default_resource_finder if JSONAPI . configuration . default_resource_finder
427- end
428-
429- # A ResourceFinder is a mixin that adds functionality to find Resources and Resource Fragments
430- # to the core Resource class.
431- #
432- # Resource fragments are a hash with the following format:
433- # {
434- # identity: <required: a ResourceIdentity>,
435- # cache: <optional: the resource's cache value>
436- # attributes: <optional: attributes hash for attributes requested - currently unused>
437- # related: {
438- # <relationship_name>: <ResourceIdentity of a source resource in find_included_fragments>
439- # }
440- # }
441- #
442- # begin ResourceFinder Abstract methods
443- def find ( _filters , _options = { } )
444- # :nocov:
445- raise 'Abstract ResourceFinder method called. Ensure that a ResourceFinder has been set.'
446- # :nocov:
447- end
448-
449- def count ( _filters , _options = { } )
450- # :nocov:
451- raise 'Abstract ResourceFinder method called. Ensure that a ResourceFinder has been set.'
452- # :nocov:
453- end
454-
455- def find_by_keys ( _keys , _options = { } )
456- # :nocov:
457- raise 'Abstract ResourceFinder method called. Ensure that a ResourceFinder has been set.'
458- # :nocov:
459- end
460-
461- def find_by_key ( _key , _options = { } )
462- # :nocov:
463- raise 'Abstract ResourceFinder method called. Ensure that a ResourceFinder has been set.'
464- # :nocov:
465- end
466-
467- def find_fragments ( _filters , _options = { } )
468- # :nocov:
469- raise 'Abstract ResourceFinder method called. Ensure that a ResourceFinder has been set.'
470- # :nocov:
471- end
472-
473- def find_included_fragments ( _source_rids , _relationship_name , _options = { } )
474- # :nocov:
475- raise 'Abstract ResourceFinder method called. Ensure that a ResourceFinder has been set.'
476- # :nocov:
477- end
424+ # Ensure that the parent's resource finder is included before inheriting from the parent is completed
425+ if !_resource_finder_included && self != JSONAPI ::Resource
426+ include_resource_finder
427+ end
428+ subclass . _resource_finder_included = _resource_finder_included
478429
479- def find_related_fragments ( _source_rids , _relationship_name , _options = { } )
480- # :nocov:
481- raise 'Abstract ResourceFinder method called. Ensure that a ResourceFinder has been set.'
482- # :nocov:
430+ check_reserved_resource_name ( subclass . _type , subclass . name )
483431 end
484432
485- def count_related ( _source_rid , _relationship_name , _options = { } )
486- # :nocov:
487- raise 'Abstract ResourceFinder method called. Ensure that a ResourceFinder has been set.'
488- # :nocov:
433+ # Set the resource finder for a resource, which will override the default_resource_finder
434+ def resource_finder ( resource_finder )
435+ @resource_finder = resource_finder
436+ include_resource_finder
489437 end
490438
491- #end ResourceFinder Abstract methods
492-
493439 def rebuild_relationships ( relationships )
494440 original_relationships = relationships . deep_dup
495441
@@ -534,7 +480,7 @@ def resource_type_for(model)
534480 end
535481 end
536482
537- attr_accessor :_attributes , :_relationships , :_type , :_model_hints
483+ attr_accessor :_attributes , :_relationships , :_type , :_model_hints , :_resource_finder_included
538484 attr_writer :_allowed_filters , :_paginator , :_allowed_sort
539485
540486 def create ( context )
@@ -1070,6 +1016,28 @@ def register_relationship(name, relationship_object)
10701016 end
10711017
10721018 private
1019+ def _resource_finder
1020+ @resource_finder ||= JSONAPI . configuration . default_resource_finder
1021+ end
1022+
1023+ def include_resource_finder
1024+ return if self == JSONAPI ::Resource
1025+ if self . _resource_finder_included
1026+ warn "#{ self . name } is including a Resource Finder when one has already been included"
1027+ end
1028+ include _resource_finder
1029+ self . _resource_finder_included = true
1030+ end
1031+
1032+ def method_missing ( m , *args , &block )
1033+ if _resource_finder_included
1034+ super
1035+ else
1036+ # Handle the case where a resource finder has not been included yet. This should only happen once per class.
1037+ include_resource_finder
1038+ send ( m , *args , &block )
1039+ end
1040+ end
10731041
10741042 def check_reserved_resource_name ( type , name )
10751043 if [ :ids , :types , :hrefs , :links ] . include? ( type )
0 commit comments