class JSONAPI::ResourceLoader
def self.active_storage_blob?(model_class)
def self.active_storage_blob?(model_class) defined?(::ActiveStorage) && model_class == ::ActiveStorage::Blob end
def self.build_resource_class_name(resource_type, namespace)
def self.build_resource_class_name(resource_type, namespace) base = "#{resource_type.singularize.classify}Resource" return base unless namespace.present? "#{namespace.to_s.camelize}::#{base}" end
def self.extract_namespace_from_model(model_class)
def self.extract_namespace_from_model(model_class) parts = model_class.name.deconstantize parts.presence&.underscore end
def self.find(resource_type, namespace: nil)
def self.find(resource_type, namespace: nil) return find_namespaced(resource_type, namespace) if namespace.present? find_flat(resource_type, namespace) end
def self.find_base_class_resource(model_class, effective_namespace)
def self.find_base_class_resource(model_class, effective_namespace) raise MissingResourceClass, model_class.name unless sti_subclass?(model_class) base_resource_type = model_class.base_class.name.demodulize.underscore.pluralize base_namespace = extract_namespace_from_model(model_class.base_class) || effective_namespace find(base_resource_type, namespace: base_namespace) end
def self.find_flat(resource_type, namespace)
def self.find_flat(resource_type, namespace) flat_class = build_resource_class_name(resource_type, nil) flat_class.constantize rescue NameError raise MissingResourceClass.new(resource_type, namespace:) end
def self.find_for_model(model_class, namespace: nil)
def self.find_for_model(model_class, namespace: nil) return ActiveStorageBlobResource if active_storage_blob?(model_class) find_resource_for_model(model_class, namespace) end
def self.find_namespaced(resource_type, namespace)
def self.find_namespaced(resource_type, namespace) namespaced_class = build_resource_class_name(resource_type, namespace) namespaced_class.constantize rescue NameError raise MissingResourceClass.new(resource_type, namespace:) unless JSONAPI.configuration.namespace_fallback find_flat(resource_type, namespace) end
def self.find_resource_for_model(model_class, namespace)
def self.find_resource_for_model(model_class, namespace) effective_namespace = namespace || extract_namespace_from_model(model_class) resource_type = model_class.name.demodulize.underscore.pluralize find(resource_type, namespace: effective_namespace) rescue MissingResourceClass try_flat_full_name_resource(model_class) || find_base_class_resource(model_class, effective_namespace) end
def self.sti_subclass?(model_class)
def self.sti_subclass?(model_class) model_class.respond_to?(:base_class) && model_class.base_class != model_class end
def self.try_flat_full_name_resource(model_class)
def self.try_flat_full_name_resource(model_class) return nil unless model_class.name.include?("::") "#{model_class.name.gsub("::", "")}Resource".constantize rescue NameError nil end