{"id":13558259,"url":"https://github.com/Swirrl/tripod","last_synced_at":"2025-04-03T13:30:52.082Z","repository":{"id":4386273,"uuid":"5523207","full_name":"Swirrl/tripod","owner":"Swirrl","description":"ActiveModel-style Ruby ORM for RDF Linked Data. Works with SPARQL 1.1 HTTP endpoints.","archived":false,"fork":false,"pushed_at":"2023-12-14T08:41:25.000Z","size":451,"stargazers_count":58,"open_issues_count":22,"forks_count":14,"subscribers_count":22,"default_branch":"master","last_synced_at":"2025-04-02T07:11:16.347Z","etag":null,"topics":["activemodel","linkeddata","orm","rails","rdf","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Swirrl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-08-23T09:48:19.000Z","updated_at":"2024-05-17T16:40:33.000Z","dependencies_parsed_at":"2023-07-06T08:33:39.751Z","dependency_job_id":"cca9f848-a6de-4b3b-9dc9-ab1a396be2da","html_url":"https://github.com/Swirrl/tripod","commit_stats":{"total_commits":290,"total_committers":12,"mean_commits":"24.166666666666668","dds":"0.31034482758620685","last_synced_commit":"76c42982b0a5ed458dcd1d714bb4a7d4964c34cc"},"previous_names":[],"tags_count":86,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swirrl%2Ftripod","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swirrl%2Ftripod/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swirrl%2Ftripod/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swirrl%2Ftripod/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Swirrl","download_url":"https://codeload.github.com/Swirrl/tripod/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247009495,"owners_count":20868564,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["activemodel","linkeddata","orm","rails","rdf","ruby"],"created_at":"2024-08-01T12:04:50.679Z","updated_at":"2025-04-03T13:30:52.058Z","avatar_url":"https://github.com/Swirrl.png","language":"Ruby","readme":"[![Build Status](https://travis-ci.org/Swirrl/tripod.svg?branch=master)](https://travis-ci.org/Swirrl/tripod)\n\n# Tripod\n\nActiveModel-style Ruby ORM for RDF Linked Data. Works with SPARQL 1.1 HTTP endpoints.\n\n* [ActiveModel](https://github.com/rails/rails/tree/master/activemodel)-compliant interface.\n* Inspired by [Durran Jordan's](https://github.com/durran) [Mongoid](http://mongoid.org/en/mongoid/) ORM for [MongoDB](http://www.mongodb.org/), and [Ben Lavender's](https://github.com/bhuga) RDF ORM, [Spira](https://github.com/ruby-rdf/spira).\n* Uses [Ruby-RDF](https://github.com/ruby-rdf/rdf) to manage the data internally.\n\n## Quick start, for using in a rails app.\n\n1. Add it to your Gemfile and bundle\n\n        gem tripod\n\n        $ bundle\n\n2. Configure it (in application.rb, or development.rb/production.rb/test.rb)\n\n        # (values shown are the defaults)\n        Tripod.configure do |config|\n          config.update_endpoint = 'http://127.0.0.1:3030/tripod/update'\n          config.query_endpoint = 'http://127.0.0.1:3030/tripod/sparql'\n          config.timeout_seconds = 30\n        end\n\n3. Include it in your model classes.\n\n        class Person\n          include Tripod::Resource\n\n          # these are the default rdf-type and graph for resources of this class\n          rdf_type 'http://example.com/person'\n          graph_uri 'http://example.com/people'\n\n          field :name, 'http://example.com/name'\n          field :knows, 'http://example.com/knows', :multivalued =\u003e true, :is_uri =\u003e true\n          field :aliases, 'http://example.com/alias', :multivalued =\u003e true\n          field :age, 'http://example.com/age', :datatype =\u003e RDF::XSD.integer\n          field :important_dates, 'http://example.com/importantdates', :datatype =\u003e RDF::XSD.date, :multivalued =\u003e true\n        end\n\n        # Note: Active Model validations are supported\n\n4. Use it\n\n        uri = 'http://example.com/ric'\n        p = Person.new(uri)\n        p.name = 'Ric'\n        p.age = 31\n        p.aliases = ['Rich', 'Richard']\n        p.important_dates = [Date.new(2011,1,1)]\n        p.save!\n\n        people = Person.all.resources #=\u003e returns all people as an array\n\n        ric = Person.find('http://example.com/ric') #=\u003e returns a single Person object.\n\n## Note:\n\nTripod doesn't supply a database. You need to install one. I recommend [Fuseki](http://jena.apache.org/documentation/serving_data/index.html), which runs on port 3030 by default.\n\n\n## Some Other interesting features\n\n## Eager Loading\n\n        asa = Person.find('http://example.com/asa')\n        ric = Person.find('http://example.com/ric')\n        ric.knows = asa.uri\n\n        ric.eager_load_predicate_triples! #does a big DESCRIBE statement behind the scenes\n        knows = ric.get_related_resource('http://example.com/knows', Resource)\n        knows.label # this won't cause another database lookup\n\n        ric.eager_load_object_triples! #does a big DESCRIBE statement behind the scenes\n        asa = ric.get_related_resource('http://example.com/asa', Person) # returns a fully hydrated Person object for asa, without an extra lookup\n\n## Defining a graph at instantiation-time\n\n        class Resource\n          include Tripod::Resource\n          field :label, RDF::RDFS.label\n\n          # notice also that you don't need to supply an rdf type or graph here!\n        end\n\n        r = Resource.new('http://example.com/foo', 'http://example.com/mygraph')\n        r.label = \"example\"\n        r.save\n\n        # Note: Tripod assumes you want to store all resources in named graphs.\n        # So if you don't supply a graph at any point (i.e. class or instance level),\n        # you will get an error when you try to persist the resource.\n\n## Reading and writing arbitrary predicates\n\n        r.write_predicate(RDF.type, 'http://example.com/myresource/type')\n        r.read_predicate(RDF.type) #=\u003e [RDF::URI.new(\"http://example.com/myresource/type\")]\n\n## Finders and criteria\n\n        # A Tripod::Criteria object defines a set of constraints for a SPARQL query.\n        # It doesn't actually do anything against the DB until you run resources, first, or count on it.\n        # (from Tripod::CriteriaExecution)\n\n        Person.all #=\u003e returns a Tripod::Criteria object which selects all resources of rdf_type http://example.com/person, in the http://example.com/people graph\n\n        Resource.all #=\u003e returns a criteria object to return resources in the database (as no rdf_type or graph_uri specified at class level)\n\n        Person.all.resources #=\u003e returns all the actual resources for the criteria object, as an array-like object\n\n        Person.all.resources(:return_graph =\u003e false) #=\u003e returns the actual resources, but without returning the graph_uri in the select (helps avoid pagination issues). Note: doesn't set the graph uri on the instantiated resources.\n\n        Person.first #=\u003e returns the first person (by crafting a sparql query under the covers that only returns 1 result)\n\n        Person.first(:return_graph =\u003e false) # as with resources, doesn't return / set the graph_uri.\n\n        Person.count  #=\u003e returns the count of all people (by crafting a count query under the covers that only returns a count)\n\n        # note that you need to use ?uri as the variable for the subject.\n        Person.where(\"?uri \u003chttp://example.com/name\u003e 'Joe'\") #=\u003e returns a Tripod::Criteria object\n\n        Resource.graph(\"http://example.com/mygraph\") #=\u003e Retruns a criteria object with a graph restriction (note: if graph_uri set on the class, it will default to using this)\n\n        Resource.find_by_sparql('SELECT ?uri ?graph WHERE { GRAPH ?graph { ?uri ?p ?o } }') #=\u003e allows arbitrary sparql. Again, use ?uri for the variable of the subjects (and ?graph for the graph).\n\n## Chainable criteria\n\n        Person.all.where(\"?uri \u003chttp://example.com/name\u003e 'Ric'\").where(\"?uri \u003chttp://example.com/knows\u003e \u003chttp://example.com/asa\u003e).first\n\n        Person.where(\"?uri \u003chttp://example.com/name\u003e ?name\").limit(1).offset(0).order(\"DESC(?name)\")\n\n## Running tests\n\nWith a Fuseki instance ready and up, edit the config in `spec/spec_helper.rb` to reflect your settings. Make sure you `bundle` to pull in all dependencies before trying to run the tests.\n\nSome tests require memcached to be set up and running. The tests that require memcached are tagged with `:caching_tests =\u003e true`; do with this information what you will. \n\n[Full Documentation](http://rubydoc.info/gems/tripod/frames)\n\nCopyright (c) 2012 [Swirrl IT Limited](http://swirrl.com). Released under MIT License","funding_links":[],"categories":["Ruby","ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSwirrl%2Ftripod","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSwirrl%2Ftripod","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSwirrl%2Ftripod/lists"}