ncbo / goo Goto Github PK
View Code? Open in Web Editor NEWGraph Oriented Objects (GOO) for Ruby. A RDF/SPARQL based ORM.
Home Page: http://ncbo.github.io/goo/
License: Other
Graph Oriented Objects (GOO) for Ruby. A RDF/SPARQL based ORM.
Home Page: http://ncbo.github.io/goo/
License: Other
Right now, calling object.load returns a boolean (I think?). It would be really nice for chaining if you could call object.load and have the instance returned. Here's a use case:
ont = Ontology.find("SNOMED").load
latest = ont.latest_submission.load
We need to configure models with the following:
validates :hasContact, :instance_of => :contact_details
To enforce that in
object.hasContact << inst
inst
is type of Contact
. Where Contact is a the :contact_details
model.
There is a problem when using goo objects without making the model call in the class definition. It happens when there is a dependent object. See code below.
class Ontology < Goo::Base::Resource
attribute :acronym, :unique => true, :cardinality => { :max => 1, :min => 1 }
attribute :name, :cardinality => { :max => 1, :min => 1 }
end
class Project < Goo::Base::Resource
attribute :name, :cardinality => { :max => 1, :min => 1 }
attribute :ontologyUsed, :instance_of => { :with => :ontology }, :cardinality => { :min => 1 }
end
p = LinkedData::Models::Project.new({
:name => "Great Project",
:ontologyUsed => [LinkedData::Models::Ontology.new(acronym: "SNOMED", name: "SNOMED CT")]
})
assert_equal false, p.exist?(reload=true)
p.save
assert_equal true, p.exist?(reload=true)
p.delete
assert_equal false, p.exist?(reload=true)
The following code results in an error when running p.save:
ArgumentError: Model ontology is not registered.
Add a custom validator for email addresses. This is needed on User, possibly elsewhere.
Supporting a "find" functionality similar to ActiveModel would be great. This will help people familiar with ActiveRecord and other common Ruby ORMs to use Goo a little easier.
I imagine several types of calls:
Person.find(:all)
Person.find(["paul", "manuel"])
Person.find("paul")
Person.find("http://goo.org/metadata/person/paul")
Person.all # wraps Person.find(:all)
Person.where(:name => "paul", :phone => "555-555-5555")
More examples here:
http://guides.rubyonrails.org/active_record_querying.html
Would be nice to see a test file for validators so we know what's available and how to use them all in one place
Using this user model
module LinkedData
module Models
class User < LinkedData::Models::Base
model :user
attribute :username, :unique => true, :single_value => true, :not_nil => true
attribute :firstName, :single_value => true
attribute :lastName, :single_value => true
attribute :created, :date_time_xsd => true, :single_value => true, :not_nil => true, :default => lambda { |record| DateTime.now }
end
end
end
The following happens
u = LinkedData::Models::User.new
u.username = "test_user"
u.valid?
=> false
u.errors
=> {:created=>
["created is nil. It does not satisfy cardinality {:max=>1, :min=>1, :instance=>#<Goo::Validators::CardinalityValidator:0x007fb3b42b7a68 @options={...}>}"]}
u.created = u.created
u.valid?
=> true
Lazy loaded object and set/get of unknow attr should throw an error. It just returns nil now.
Need to have custom validations that can be defined outside of the framework base code.
We can save time by disabling reasoning by default. The only queries that actually need enabling reasoning are some class queries to retrieve standard slots. All metadata queries do not require reasoning.
At the moment there is no support to choose conjunctive or disjunctive.
Any color that has blue AND white as code and maybe not only those values. Same as AND_INCLUSIVE
:
Color.search({:code => ["blue","white"]})
A color that contains blue OR white and no other values.
Color.search({:code => [ ["blue","white"], OR_EXCLUSIVE ] })
Same for AND_EXCLUSIVE and OR_INCLUSIVE.
For some reason the validators need to be at the root module in order to be found.
At the moment we do not have the ability to search. It would be useful to do things like this.
personList = Person.search(:name , "foo")
personList.each do |p|
puts p.resource_id #lazy loading at this point
p.load #loads the entire object
end
Also the ability to search by Resources.
personList = Person.search(:friendOf , otherPerson)
personList.each do |p|
puts p.resource_id #lazy loading at this point
p.load #loads the entire object
end
To follow ruby convention.
Offset limit and some kind of ordering when retrieving Goo objects.
Project.all(:limit=> 10, :offset => 100, :sort => { :with => [:name, :asc] )
Project.find(:attribute => "value" :limit=> 10, :offset => 100, :sort => { :with => [:name, :asc] )
Project.count({})
This should be done accordingly to the issue about changing the API for search
We should have this like ...
vocabs.register(:omv,"http://omv.org/ontology/", [:name])
instead of
vocabs.register(:omv, IRI.new("http://omv.org/ontology/"), [:name])
Model.all :load_attrs => [:attr1, :attr2]
In some conditions calling the valid? method results in an exception. It looks like when there are two attributes with :unqiue => true and only one has been set. For example:
os = LinkedData::Models::OntologySubmission.new
os.submissionId = 1
os.valid?
=> ArgumentError: Field acronym has no value. Value is needed to generate resource id
In models with this definition:
attribute :iri_value, :instance_of => { :with => RDF::IRI }, :single_value => true
if the object is updated then a duplicated triple is generated for this attribute.
Reviews goes into the default namespace:
class Review
attribute :name
attribute :name , { options }
end
or in this second case the default namespace for Review is :other_ns
. That ns is use by default by attributes unless stated otherwise in options:
class Review
namespace :other_ns
attribute :name
attribute :name , { options }
end
We need to control for instance when we want to delete a user and there are other objects that are linked to that user.
A dsl option in model
class X << Resource
model :x ,
:name_with => lambda { |record| IRI.new("http://xxx/"+record.attr }
end
At the moment we need to do this to load a resource:
x = Person.new
x.load("http://foo.bar/x")
puts x.name
We need to support also the creation without knowing the model. Something like:
x = Goo.load("http://foo.bar/x")
puts x.class #returns Person
puts x.name
Do not know if this tool is the best option @palexander ?
https://github.com/bborn/simplecov
Low priority bug but definitely a nice to have thing.
It would be nice to have a to_turtle method that would convert objects to turtle triples. This would get used the in BP objects as a basis for outputting RDF-serialized versions of the objects.
We should have an offline mode that doesn't interact with the triplestore and instead uses some internal mechanism to store and retrieve data. This would be useful in allowing basic development and testing without a 4store instance.
Looks like the model could be defined by default by using self.class.name.to_underscore.to_sym
Note that to_underscore doesn't exist, but there are several implementations we could use offered here:
http://stackoverflow.com/questions/1509915/converting-camel-case-to-underscore-case-in-ruby
Would be cool to have an option to have date fields populated on save or instantiation. Here's what I imagine:
class Category < Goo::Base::Resource
model :project
attribute :creator, :cardinality => { :max => 1, :min => 1 }
attribute :created, :date_time_xsd => true, :populate_date => :create, :cardinality => { :max => 1, :min => 1 }
attribute :updated, :date_time_xsd => true, :populate_date => :update, :cardinality => { :max => 1, :min => 1 }
end
This would save a lot of boilerplate code. In ActiveRecord you get the "created" and "updated" fields for every object unless you specify otherwise.
๐
When creating a goo object, it would be good to be able to define default values for attributes that would get created on initialization. Some way to override the default would be nice.
When we name a resource, we should be allowed to specify how the naming happens using a lambda
After this is done, we should consider removing the acronym attribute from OntologySubmission in the ontologies_linked_data library
Support something like ...
class Ontology
attribute :submissions,
:inverse_of => { :with => :ontology_submission ,
:attribute => :ontology }
end
It basically allow us to have the connection only in one place in the triple and represent an inverse property in code
.
Something like status and person. Save person with a given status.
Something like
ontST = OntologyStatus
list = Ontology.search(:status, ontST)
Even better
list = Ontology.search(:status, { :code => "PARSED" })
This would search for things that have one property with code "PARSED"
The list returned here could contain any type of model.
list = Goo::Base::Resource.search(:status, { :code => "PARSED" })
:not_nil => false
is treated exactly as :not_nil => true
The update strategy now is not efficient and replaces the whole object. Change it so that it only run a SPARQL update
This component is becoming too big. The following methods need to be reviewed:
For a goo object, we should provide an option to retrieve the class for a given attribute when that attribute is associated to another object via the :instance_of option in the attribute DSL.
For example:
class Review < Goo::Base::Resource
model :review
attribute :creator, :instance_of => { :with => :user }, :cardinality => { :max => 1, :min => 1 }
end
> cls = Review.range_class(:creator)
> cls == User
=> true
When initializing, it would be nice to not have to provide an empty attributes array. Unless there is a reason to require it, I mean.
Would make it so you could just do:
GooObject.new
instead of:
GooObject.new({})
Code like ...
contact_a = ContactDetails.new({:contact_name => "name a"})
contact_b = ContactDetails.new({:contact_name => "name b"})
ont = Ontology.new({:name => "SNOMED Clinical Terms",
(...)
:hasContact => [contact_a, contact_b]})
ont.save
Generates the following query that is wrong ...
'INSERT DATA { GRAPH <http://data.bioontology.org/metadata/Ontology> {
(...)
<http://data.bioontology.org/metadata/ontology/SNOMEDCT> <http://data.bioontology.org/metadata/hasContact> [
_:bNode3499835456282537575 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://data.bioontology.org/metadata/ContactDetails>;
_:bNode3499835456282537575 <http://data.bioontology.org/metadata/contactName> """name a"""^^<http://www.w3.org/2001/XMLSchema#string>;
_:bNode3499835456282537575 <http://data.bioontology.org/metadata/uuid> """4c1eaf50-1684-0130-6005-64ce8f34ad34"""^^<http://www.w3.org/2001/XMLSchema#string> ] .
<http://data.bioontology.org/metadata/ontology/SNOMEDCT> <http://data.bioontology.org/metadata/hasContact> [
_:bNode155722364050198075 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://data.bioontology.org/metadata/ContactDetails>;
_:bNode155722364050198075 <http://data.bioontology.org/metadata/contactName> """name b"""^^<http://www.w3.org/2001/XMLSchema#string>;
_:bNode155722364050198075 <http://data.bioontology.org/metadata/uuid> """4c1eb3e0-1684-0130-6005-64ce8f34ad34"""^^<http://www.w3.org/2001/XMLSchema#string> ] .
} }
The blank nodes are included in the query with a three element triple.
URI encoding when generating IDs. Initial implementation allow spaces. It is unclear if find
works with encoded characters.
This need to revised. @palexander what characters do we allow for fields that are going to be used for generating IRIs. Somehow we have to validate for that and encode the ones that are valid.
The way it works now it makes to work as in where SQL clause and it is confusing. Default behaviour should be
:load_attrs => [ :name ]
and that should run with optional in the SPARQL query.
Example omv:creationDate
For consistency with where
and all
and to avoid confusion and improve performance. Find might be use to see if a resource exists.
Mostly when iterating a list that comes out of a search.
> p = Person.new
> p.respond_to?("name")
=> false
> p.respond_to?("name=")
=> false
Document main API calls in Goo.
We will need to support lookups based on the last fragment of an id IRI. For example:
# This works
Ontology.find("http://blah.org/ontologies/snomed")
# So should this
Ontology.find("snomed")
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.