ruby-rdf / spira Goto Github PK
View Code? Open in Web Editor NEWSpira is a framework for viewing RDF data as model objects
Home Page: http://rubygems.org/gems/spira
License: The Unlicense
Spira is a framework for viewing RDF data as model objects
Home Page: http://rubygems.org/gems/spira
License: The Unlicense
As a follow-up to ruby-rdf/rdf#214, the spira codebase contains at least two use of splat argument method invoked with a potentially large number of statements:
These should be refactored to use RDF::Writable#insertn
and RDF::Writable#insertn
; the speedup on these (seldom invoked) utility methods should be quite noticeable.
Taken from an example in the readme:
require 'spira'
class Person < Spira::Base
configure :base_uri => "http://example.org/example/people"
property :name, :predicate => RDF::Vocab::FOAF.name, :type => String
property :age, :predicate => RDF::Vocab::FOAF.age, :type => Integer
end
Spira.repository = RDF::Repository.new
bob = RDF::URI("http://example.org/people/bob").as(Person)
bob.age = 15
bob.name = "Bob Smith"
bob.save!
bob.each_statement {|s| puts s}
# /home/$user/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/rdf-3.0.5/lib/rdf.rb:67:in
# `const_missing': uninitialized constant RDF::Vocab (NameError)
# Did you mean? RDF::VOCABS
# from test.rb:6:in `<class:Person>'
# from test.rb:2:in `<main>'
Adding require 'rdf/vocab'
solves this issue. It is in the .gemspec file as a development dependency.
I think there could be at least two solutions here:
require 'rdf/vocab'
require 'rdf/vocab'
What do you think is the best approach?
I have the following resource definition:
class City
include Spira::Resource
@vocabulary = 'http://s.opencalais.com/1/pred'
base_uri 'http://d.opencalais.com/er/geo/city/ralg-geo1'
type RDF::URI.new('http://s.opencalais.com/1/type/er/Geo/City')
property :name, type: XSD.string, predicate: predicate_uri('name')
property :short_name, type: XSD.string, predicate: predicate_uri('shortname')
property :contained_by_state, type: XSD.string, predicate: predicate_uri('containedbystate')
property :contained_by_country, type: XSD.string, predicate: predicate_uri('containedbycountry')
property :latitude, type: XSD.string, predicate: predicate_uri('latitude')
property :longitude, type: XSD.string, predicate: predicate_uri('longitude')
property :subject, type: RDF::URI, predicate: predicate_uri('subject')
end
and when I try to get a resource from the repository I get the following exception:
/home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/spira-0.0.12/lib/spira/resource/instance_methods.rb:334:in `attribute_get': undefined method `[]' for nil:NilClass (NoMethodError)
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/spira-0.0.12/lib/spira/resource/dsl.rb:272:in `block in add_accessors'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/spira-0.0.12/lib/spira/resource/instance_methods.rb:59:in `reload'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/spira-0.0.12/lib/spira/resource/instance_methods.rb:42:in `initialize'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/spira-0.0.12/lib/spira/resource/class_methods.rb:90:in `new'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/spira-0.0.12/lib/spira/resource/class_methods.rb:90:in `project'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/spira-0.0.12/lib/spira/resource/class_methods.rb:69:in `for'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/spira-0.0.12/lib/spira/resource/class_methods.rb:202:in `block in each'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/mixin/enumerable.rb:341:in `call'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/mixin/enumerable.rb:341:in `block in each_subject'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/repository.rb:341:in `call'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/repository.rb:341:in `block (4 levels) in query_pattern'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/repository.rb:339:in `each'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/repository.rb:339:in `block (3 levels) in query_pattern'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/repository.rb:336:in `each'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/repository.rb:336:in `block (2 levels) in query_pattern'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/repository.rb:333:in `each'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/repository.rb:333:in `block in query_pattern'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/repository.rb:330:in `each'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/repository.rb:330:in `query_pattern'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/mixin/enumerable.rb:152:in `each'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/mixin/enumerable.rb:152:in `each_statement'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rdf-0.3.11.1/lib/rdf/mixin/enumerable.rb:337:in `each_subject'
from /home/guido/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/spira-0.0.12/lib/spira/resource/class_methods.rb:201:in `each'
from test.rb:5:in `each'
from test.rb:5:in `to_a'
from test.rb:5:in `<main>'
But when I change the subject property definition and replace "subject" to anything else it works. So it seems that "subject" is reserved in some way.
Resources with has_many relationships which derived from Spira::Base do cascade inserting?
I'm just getting to grips with Spira and I've found something that strikes me as odd (the mailing list looks a bit quiet so I'm posting here instead). I wonder if this is an expectation set by the OOP/ ActiveRecord world that simply doesn't apply in the graph/ RDF world...
I expect Spira::Base#count to return the count of objects of the relevant type - i.e. the distinct count of "?s a <model_type>", the number of instances. Instead #count returns the count of occurrences of those subjects - i.e. the number of triples where a "?s a <model_type>" is the subject. In OOP terms this is basically like counting the number of attributes which is certainly not what I would expect.
I realise that what might need 'fixing' is in fact my expectations about how objects work in a graph world. If so, I'd be very grateful if someone could elaborate on this.
Nevertheless the apparent congruence between the AR and Spira public APIs leads me to believe that I won't be the only one making this mistake! It might be clearer, for example, if Spira distinguished between a #count
and a #count_of_subjects
method.
I need use with example .
class Tag < Spira::Base
configure :base_uri => "http://www.xpto.com/tags"
property :preferred_label, :predicate => SKOS.prefLabel, :type => XSD.string
property :alternative_labels, :predicate => SKOS.altLabel, :type => XSD.string
end
class TagsController < ApplicationController
def index
@tag = Tag.all
end
end
end
Erro Cannot count a Tag without a reference type URI ...
Hi, I'm using git-flow on the other RDF.rb eco-system gems, and have established the current develop branch to prepare for a forthcoming 1.1 release of most of the gems. Unless I hear otherwise, I plan to do the same for Spira.
Git-flow works great for maintaining different branches of a repo and automating most of the feature/prepare/release cycle.
It looks like the gems that use git references in Gemfile are causing the tests to fail.
While the last build on develop passed, I re-ran the build today and it failed. I noticed the issue when I opened pr #53, which is just a change to the README, but the build failed.
I can't seem to get any of the examples to work fully; everything is fine until I try to call save!
on an object, which gives me
NoMethodError: undefined method `has_subject?' for nil:NilClass
from /home/wstrinz/.rvm/gems/ruby-1.9.3-p429/gems/spira-0.5.0/lib/spira/persistence.rb:285:in `new_record?'
If I call bob.subject
it returns the expected uri, but maybe this is something other than the subject
that the new_record?
method is looking for?
It seems to be the same for the Person, Artist, and CD objects in the examples in the readme. I dug into the code a bit, but I couldn't figure out what was going on since 'subject' seems to be some kind of reserved word and I'm not quite sure how it's supposed to work. Is this just happening because I don't actually have anywhere to save the resource to? I thought it would just stay in memory, but if not maybe a note could be added about this to the examples? I'd be happy to submit a PR if that's the case :)
i have these statements
when i want to save the movie. it gives me this error.
undefined method `literal?' for #Hash:0x000001062397c0
Any idea?
Thanks
@cordawyn, @gkellogg Travis CI build failed because of the version of RDF used. See https://travis-ci.org/ruby-rdf/spira/jobs/13634713.
I can reproduce the problem. Currently Spira only works with RDF <= 1.0.7. Could you provide a pull request that fix the problem and make it compliant with RDF 1.0.10 ?
Thanks.
NoMethodError in ProjectsController#create
undefined method `call' for <Project:70300670299740 @subject: _:g70300670299680>:Project
Rails.root: /home/ranielli/ruby/prolod01
Application Trace | Framework Trace | Full Trace
app/controllers/projects_controller.rb:17:in `create'
Request
Parameters:
{"utf8"=>"โ",
"authenticity_token"=>"PC8I7nNTHZclFYf67GHu7jLFcYr+TbKxGtczxTgPbWQ=",
"project"=>{"name"=>"ocarro",
"description"=>"carro do ano"},
"commit"=>"Create Project"}
I'm getting the following error when I try to reference a Spira::Base
in a Rails (3.2.14) controller:
Spira::NoRepositoryError
I'm using the current master
version of this gem. I'm currently setting the repository in an initializer. Presumably this error is related to the new repository threadsafe feature, as I can access Spira.repository
and my Spira::Base
objects just fine from Rails console.
I can get around this by doing (in my controller):
before_filter do
Spira.repository ||= RDF::DataObjects::Repository.new('sqlite3:test.db')
end
but I don't want to have to do this. Is there some way to make the repository play nice with Rails controllers, or is there a better/recommended place to define my repository where this won't be an issue?
Is there a plan to make Spira support find and find_all active record methods?
example Rails with Spira , any?Example CRUD
I also checked specs in spira about inheritence but it seems not working for me. Here is my structure,
require 'spira'
module Knowledgebase
class Celebrity < DakickThing
configure :base_uri => Semantic::Utilities.create_base_individual_uri(DAK_SEM_CONFG["individual_base"], self.name.split("::")[1].pluralize.tableize)
type Semantic::OntDakick.Celebrity
end
end
require 'spira'
module Knowledgebase
class DakickThing < OntClass
type Semantic::OntDakick.DakickThing
end
end
require 'spira'
require 'rdf'
module Knowledgebase
class OntClass < Spira::Base
include RDF
include Semantic::ExternalOntologyUtility
include Semantic::Utilities
type RDFS.Resource
type OWL.Class
end
end
Here is my unit test
it 'contains derived types' do
include RDF
types = Set.new [RDF::OWL.Class, RDF::RDFS.Resource, Semantic::OntDakick.DakickThing, Semantic::OntDakick.Celebrity]
Knowledgebase::Celebrity.types.should eql types
end
and here is my output
expected: #<Set: {#<RDF::URI:0x844b7f38(http://www.w3.org/2002/07/owl#Class)>, #<RDF::URI:0x844c794c(http://www.w3.org/2000/01/rdf-schema#Resource)>, #<RDF::URI:0x82fd7528(http:://localhost:3000/resource/DakickThing)>, #<RDF::URI:0x82fdff84(http:://localhost:3000/resource/Celebrity)>}>
got: #<Set: {#<RDF::URI:0x82fdff84(http:://localhost:3000/resource/Celebrity)>, #<RDF::URI:0x80640d2c(http://xmlns.com/foaf/0.1/Person)>}>
i have an ontology which users can rate different concepts.
lets say
:user :rates :celebrity
:user :rates :movie
so i started to create a user class
class User < Spira::Base
has_many :rates, :predicate => OntDakick.rates, :type => :Celebrity,:Movie #my main issue is here
end
user = User.for("")
user.rates
output is []
.Thats ok by now.Now I'm trying to add a celebrity which user rates.
rating.rates << Celebrity.for("")
But,
rating.rates
output is []
This is my first problem.Second one is how to define predicates with multiple ranges.
Thanks
Spira is currently not threadsafe. Working in parallel on 2 different repositories will fail.
The way Spira currently works it only pulls down information into the object about properties you've defined. Is there any plan to pull down the entire graph?
If it clarifies, https://github.com/ruby-rdf/spira/blob/master/lib/spira/persistence.rb#L382-L391 will pull the entire graph from a repository but only set values for those properties it knows about. There are cases where it would be good for me to have access to the graph for that subject within the object.
You have the following sample in your readme:
class Man < Spira::Base
type RDF::URI.new('http://example.org/people/father')
type RDF::URI.new('http://example.org/people/cop')
end
So when I understand this correctly, all men instantiated with m = Man.new
are cops and fathers.
But what when m
is a fire fighter?
Do I need to set up another class ManFireFighter
?
Or when he gets retired.
Do I need to get his attributes and instantiate a new class of ManRetiredFireFighterAndGrandfather
?
As this does not seem feasible, I ask myself how to set the type on instance level?
Hello,
I tried to bundle update one of our existing projects which uses spira. Upgrading activesupport dependency from v5.1.6 to v5.2.0 seems to break spira, as shown in the stacktrace below:
bash-4.2$ bundle exec rspec ./spec/serializers/subject_spec.rb:41
Run options: include {:locations=>{"./spec/serializers/subject_spec.rb"=>[41]}}
SemanticEnrichment::Serializers::Subject
#load
returns a Subject (FAILED - 1)
Failures:
1) SemanticEnrichment::Serializers::Subject#load returns a Subject
Failure/Error: serializer.load(subject_use.repository, subject_use.hooks.first.to_s)
NoMethodError:
undefined method `clear' for nil:NilClass
# ./.bundle/ruby/gems/spira-2.1.0/lib/spira/base.rb:288:in `reset_changes'
# ./.bundle/ruby/gems/spira-2.1.0/lib/spira/base.rb:162:in `reload'
# ./.bundle/ruby/gems/spira-2.1.0/lib/spira/base.rb:124:in `initialize'
# ./.bundle/ruby/gems/spira-2.1.0/lib/spira/persistence.rb:195:in `new'
# ./.bundle/ruby/gems/spira-2.1.0/lib/spira/persistence.rb:195:in `project'
# ./.bundle/ruby/gems/spira-2.1.0/lib/spira/persistence.rb:176:in `for'
...
I traced the problem to Spira::Base#reset_changes, which seems to assume too much about activesupport internals: for example, the @changed_attributes
instance variable has been refactored out in activesupport v5.2.0 (it has been replaced with a method which returns a frozen HashWithIndifferentAccess, which cannot be reset anymore, thus breaking Spira::Base#reset_changes
).
Can you investigate the issue? Meanwhile, I will add gem 'activesupport', '>= 5.0', '< 5.2'
to my Gemfiles.
https://github.com/ruby-rdf/spira/blob/master/lib/spira/base.rb#L190
# TODO: define behavior for equality on subclasses.
# TODO: should we compare attributes here?
I think we should compare attributes here.
Also for its (anoymous) nodes.
The reset_changes method is the base.rb is throwing nil:NilClass
when trying to clear the @changed_attributes
Line 288 in 5cfaa9c
/Users/mohideen/.rvm/gems/ruby-2.4.0/gems/spira-3.0.0/lib/spira/base.rb:288:in `reset_changes': undefined method `clear' for nil:NilClass (NoMethodError)
from /Users/mohideen/.rvm/gems/ruby-2.4.0/gems/spira-3.0.0/lib/spira/base.rb:162:in `reload'
from /Users/mohideen/.rvm/gems/ruby-2.4.0/gems/spira-3.0.0/lib/spira/base.rb:124:in `initialize'
from /Users/mohideen/.rvm/gems/ruby-2.4.0/gems/spira-3.0.0/lib/spira/persistence.rb:195:in `new'
from /Users/mohideen/.rvm/gems/ruby-2.4.0/gems/spira-3.0.0/lib/spira/persistence.rb:195:in `project'
from /Users/mohideen/.rvm/gems/ruby-2.4.0/gems/spira-3.0.0/lib/spira/persistence.rb:176:in `for'
from /Users/mohideen/.rvm/gems/ruby-2.4.0/gems/spira-3.0.0/lib/rdf/ext/uri.rb:16:in `as'
from /Users/mohideen/.rvm/gems/ruby-2.4.0/gems/worldcat-discovery-1.2.0/lib/worldcat/discovery/bib.rb:188:in `search'
Context: The problem occurs when RDF URI is requested to be modeled as
a class which is an extension of the Spira::Base class.
The error does not happen if change the following code
@changed_attributes.clear
to
@changed_attributes.clear if changed?
Is this a bug in the code or am I not using this correctly?
I just came accross this issue on yard lsegal/yard#1017
Basically github requires this style of link [changelog](CHANGELOG.md)
but yard requires this {file:CHANGELOG.md}
I changed the links in the readme to work on github in pr #53
Now the link works in the github readme, but it's broken in the docs on rubygems.
If you go to the readme on rubygems and follow the link to the changelog, you'll get a not found error for changes.md
Do you think the fix provided in the issue would make sense for spira?
Or should we choose between github or yard style links?
I have a class
class Version < Spira::Base
type RDF::URI.new(DOAP.Version)
property :name, :predicate => DOAP.name, :type => XSD.string
property :created, :predicate => DOAP.created, :type => XSD.date
end
version = RDF:Node.new.as(Version)
version.name = ' xpto'
version.save
error
ArgumentError: Cannot create identifier for Version by String without base_uri; an RDF::URI is required.
Time's moved on, and changes to dependent gems are getting in the way. Consider updating to moving to 6.1 versions of activesupport/activemodel in the next release.
It would be nice if reflections
were reserved for associations
, that is, relationships with other Spira::Base
objects. Reflections could be defined for :has_many
and :has_one
relationships, while serialization could be handled elsewhere (though has_many
associations would be "serialized" of course).
I've forked the gem and made a few changes (primarily to persistence.rb
), to separate these concerns. I've created a :serialize
(boolean) flag on Spira::Base.properties
values to differentiate properties that should act like arrays vs. singular objects.
I've added a couple of short specs to test this behavior, and all tests are passing.
Reserving reflections for associated Spira::Base
objects makes it easier to resolve an object's associations (and those objects' associations, etc.).
Is there any plan to add this separation of concerns to Spira? If not, are you interested in the idea and open to pull requests? Sorry if I'm going about this the wrong way--I'm a GitHub amateur.
Spira wasn't maintained in the last few years. Slava Kravchenko has done a lot of refactoring on Spira in his branch activemodelish. I think it might be very interesting to integrate it as a new branch on ruby-rdf/spira : the code is much cleaner and use more ruby patterns than the specific DSL of Spira.
See https://github.com/cordawyn/spira for more information.
Is it possible to log spira sparql queries?
irb(main):029:0> teste = Address.for(RDF::Node.new)
=> <Address:44192720 @subject: _:g44192860>
irb(main):030:0> teste.save
ArgumentError: Cannot create identifier for Address by String without base_uri; an RDF::URI is required
This issue occurs when connected to Fuseki:
class Article < Spira::Base
end
Article.new.save!
Article.new.new_record? # => false
(This is an attempt to pair down what is a more complex model on my end; hope it conveys the bug.)
Tracing through:
# A resource is considered to be new if the repository
# does not have statements where subject == resource type
def new_record?
!self.class.repository.has_subject?(subject)
end
CONSTRUCT { _:g13426267119880 ?g13427767297260 ?g13427767296240 . } WHERE { _:g13426267119880 ?g13427767297260 ?g13427767296240 . }
That blank node acts as a variable, so it matches so long as there is anything in the backing store. In other words, #new_record?
produces true
so long as any triple exists in the backing store.
Elsewhere:
def materizalize
if new_record? && subject.anonymous? && type
# TODO: doesn't subject.anonymous? imply subject.id == nil ???
@subject = self.class.id_for(subject.id)
end
end
Might be time to resolve that TODO.
This shows in Rails like so:
<%= form_for Article.new do |form| %>
<% end %>
#form_for
eventually calls @article.id
, which then crashes.
require 'spira'
class Project < Spira::Base
configure :base_uri => "http://www.xpto.com/projects"
type RDf::URI.new("http://usefulinc.com/ns/doap#Project")
property :name, :predicate => DOAP.name, :type => XSD.string
end
test = Project.for('xpto')
Error
/home/ranielli/ruby/prolod01/app/models/project.rb:10:in initialize': wrong number of arguments(1 for 0) (ArgumentError) from /home/ranielli/ruby/prolod01/app/models/project.rb:10:in
new'
from /home/ranielli/ruby/prolod01/app/models/project.rb:10:in <class:Project>' from /home/ranielli/ruby/prolod01/app/models/project.rb:5:in
The Homepage and Documentation link from https://rubygems.org/gems/spira point there.
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.