diff --git a/Gemfile.lock b/Gemfile.lock index cf0babe..f1b4298 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -17,16 +17,16 @@ PATH GEM remote: https://rubygems.org/ specs: - activesupport (7.0.8.6) + activesupport (7.0.8.7) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) - bigdecimal (3.1.8) + bigdecimal (3.1.9) coderay (1.1.3) - concurrent-ruby (1.3.4) + concurrent-ruby (1.3.5) crack (1.0.0) bigdecimal rexml @@ -37,35 +37,35 @@ GEM faraday-excon (2.0.0) excon (>= 0.27.4) faraday (~> 2.0.0.alpha.pre.2) - faraday-multipart (1.0.4) - multipart-post (~> 2) + faraday-multipart (1.1.0) + multipart-post (~> 2.0) faraday-net_http (2.1.0) - hashdiff (1.1.1) - i18n (1.14.6) + hashdiff (1.1.2) + i18n (1.14.7) concurrent-ruby (~> 1.0) lz4-ruby (0.3.3) method_source (1.1.0) - minitest (5.25.1) + minitest (5.25.4) multi_json (1.15.0) multipart-post (2.4.1) - oj (3.16.6) + oj (3.16.9) bigdecimal (>= 3.0) ostruct (>= 0.2) - ostruct (0.6.0) + ostruct (0.6.1) parallel (1.26.3) - power_assert (2.0.4) - pry (0.14.2) + power_assert (2.0.5) + pry (0.15.2) coderay (~> 1.1) method_source (~> 1.0) public_suffix (5.1.1) - rack (3.1.8) + rack (3.1.9) rake (13.2.1) request_store (1.7.0) rack (>= 1.4) - rexml (3.3.9) + rexml (3.4.0) ruby2_keywords (0.0.5) spawnling (2.1.5) - test-unit (3.6.2) + test-unit (3.6.7) power_assert tzinfo (2.0.6) concurrent-ruby (~> 1.0) diff --git a/lib/ontologies_api_client/base.rb b/lib/ontologies_api_client/base.rb index a4404df..49385f4 100644 --- a/lib/ontologies_api_client/base.rb +++ b/lib/ontologies_api_client/base.rb @@ -66,6 +66,13 @@ def type @type end + def self.explore(id) + path = self.respond_to?(:collection_path) ? collection_path : '' + id = "#{path}/#{id}" unless id.include?(path) + inst = self.new(values: {id: id}) + LinkedData::Client::LinkExplorer.new({}, inst) + end + ## # Retrieve a set of data using a link provided on an object # This instantiates an instance of this class and uses diff --git a/lib/ontologies_api_client/collection.rb b/lib/ontologies_api_client/collection.rb index a4d34c2..2e98cc8 100644 --- a/lib/ontologies_api_client/collection.rb +++ b/lib/ontologies_api_client/collection.rb @@ -29,14 +29,15 @@ def method_missing(meth, *args, &block) ## # Get all top-level links for the API def top_level_links(link = LinkedData::Client.settings.rest_url) - HTTP.get(link) + @top_level_links ||= {} + @top_level_links[link] ||= HTTP.get(link) end ## # Return a link given an object (with links) and a media type def uri_from_context(object, media_type) object.links.each do |type, link| - return link if link.media_type && link.media_type.downcase.eql?(media_type.downcase) + return link.dup if link.media_type && link.media_type.downcase.eql?(media_type.downcase) end end diff --git a/lib/ontologies_api_client/link_explorer.rb b/lib/ontologies_api_client/link_explorer.rb index 5d6fcc1..c3453f3 100644 --- a/lib/ontologies_api_client/link_explorer.rb +++ b/lib/ontologies_api_client/link_explorer.rb @@ -11,11 +11,18 @@ def initialize(links, instance) @instance = instance end + + def get(params = {}) + get_link(@instance.id, params) + end + def method_missing(meth, *args, &block) if combined_links.key?(meth.to_s) explore_link(meth, *args) elsif meth == :batch explore_link(args) + elsif !@instance.id.blank? + forward_explore(meth, *args) else super end @@ -43,10 +50,7 @@ def explore_link(*args) ids = link.map {|l| l.to_s} value_cls.where {|o| ids.include?(o.id)} else - url = replace_template_elements(link.to_s, replacements) - value_cls = LinkedData::Client::Base.class_for_type(link.media_type) - params[:include] ||= value_cls.attributes(full_attributes) - HTTP.get(url, params) + get_link(link, params, replacements, full_attributes) end end @@ -56,6 +60,22 @@ def combined_links private + def forward_explore(meth, *args) + sub_id = Array(args).find { |x| x.is_a?(String) } || '' + link = "#{@instance.id}/#{meth}/#{CGI.escape(sub_id)}".chomp('/') + @instance.id = link + LinkExplorer.new(@links, @instance) + end + + def get_link(link, params, replacements = [], full_attributes = {}) + url = replace_template_elements(link.to_s, replacements) + if link.respond_to? :media_type + value_cls = LinkedData::Client::Base.class_for_type(link.media_type) + params[:include] ||= value_cls.attributes(full_attributes) + end + HTTP.get(url, params) + end + def replace_template_elements(url, values = []) return url if values.nil? || values.empty? values = values.dup @@ -94,4 +114,4 @@ def linkable_attributes end end end -end \ No newline at end of file +end diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..83aa57a --- /dev/null +++ b/mise.toml @@ -0,0 +1,2 @@ +[tools] +ruby = "2.7.8" diff --git a/test/models/test_explore.rb b/test/models/test_explore.rb new file mode 100644 index 0000000..50a67f4 --- /dev/null +++ b/test/models/test_explore.rb @@ -0,0 +1,45 @@ +require_relative '../test_case' +require 'pry' + +module Models + def self.method_missing + binding.pry + end +end +class LinkExploreTest < LinkedData::Client::TestCase + + def test_explore + sub_direct_explore = LinkedData::Client::Models::Ontology.explore('MEDDRA') + .latest_submission + .get(include: 'all') + + sub_indirect_explore = LinkedData::Client::Models::Ontology.find('MEDDRA').explore.latest_submission + sub_direct_explore.to_hash.each do |key, value| + value_to_compare = sub_indirect_explore[key] + if value.class.ancestors.include?(LinkedData::Client::Base) + value = value.to_hash + value_to_compare = value_to_compare.to_hash + end + assert_equal value, value_to_compare + end + end + + def test_explore_class + + id = 'http://purl.org/sig/ont/fma/fma62955' + cls = LinkedData::Client::Models::Ontology.explore('FMA') + .classes(id) + .children + .get + + assert_not_empty cls.collection + + cls = LinkedData::Client::Models::Ontology.explore('FMA') + .classes(id) + .children + .get(include: 'prefLabel') + + assert_not_empty cls.collection + end + +end