samvera / active_fedora Goto Github PK
View Code? Open in Web Editor NEWA Rails interface to the Fedora repository, akin to ActiveModel
License: Other
A Rails interface to the Fedora repository, akin to ActiveModel
License: Other
Use this method somewhere in AF:
samvera/rubydora@88dc4bb
(to attach questionable tests)
Presently, I believe, ActiveFedora::Base.reindex_everything will query all of the fedora objects and reindex them in SOLR. This could create a problem in which an object in Fedora is loaded by a Rails application that does not have knowledge of that object's Ruby representation.
I believe we should be able to reindex based on a namespace or an array of pids.
Another concern is that we are loading into memory all of fedora search results; Instantiating numerous Rubydora::DigitalObject. I'm assuming that this could be a very large memory use case.
Rails console examples:
1.9.3p392 :001 > class TestDelegate < ActiveFedora::Base
1.9.3p392 :002?> has_metadata "descMetadata", type: ActiveFedora::QualifiedDublinCoreDatastream
1.9.3p392 :003?> delegate_to "descMetadata", [:title, :identifier, :creator, :source]
1.9.3p392 :004?> end
=> [:title, :identifier, :creator, :source]
1.9.3p392 :007 > t = TestDelegate.create(:title => "Test")
=> #<TestDelegate pid:"changeme:12", title:["Test"], identifier:[], creator:[], source:[]>
# DulHydra::Models::Base subclasses ActiveFedora::Base
# See https://github.com/duke-libraries/dul-hydra/blob/master/lib/dul_hydra/models/base.rb
# The same delegate_to is provided as in the above TestDelegate example via
# https://github.com/duke-libraries/dul-hydra/blob/master/lib/dul_hydra/models/describable.rb
# This does not throw an error in AF 5.6.2 and earlier 5.x releases.
1.9.3p392 :010 > class TestDelegate2 < DulHydra::Models::Base
1.9.3p392 :011?> end
=> nil
1.9.3p392 :012 > t = TestDelegate2.create(:title => "Test")
NoMethodError: undefined method `[]' for nil:NilClass
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/active-fedora-6.0.0/lib/active_fedora/delegating.rb:25:in `array_setter'
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/active-fedora-6.0.0/lib/active_fedora/delegating.rb:16:in `[]='
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/active-fedora-6.0.0/lib/active_fedora/delegating.rb:132:in `block in create_delegate_setter'
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/active-fedora-6.0.0/lib/active_fedora/attributes.rb:13:in `block in attributes='
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/active-fedora-6.0.0/lib/active_fedora/attributes.rb:12:in `each'
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/active-fedora-6.0.0/lib/active_fedora/attributes.rb:12:in `attributes='
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/active-fedora-6.0.0/lib/active_fedora/attributes/serializers.rb:26:in `attributes='
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/active-fedora-6.0.0/lib/active_fedora/base.rb:78:in `initialize'
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/active-fedora-6.0.0/lib/active_fedora/persistence.rb:110:in `new'
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/active-fedora-6.0.0/lib/active_fedora/persistence.rb:110:in `create'
from (irb):12
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
from /Users/dc/.rvm/gems/ruby-1.9.3-p392@dul-hydra-hh6/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
So we can run things like:
class Libraray < ActiveFedora::Base
has_many :books
end
class Book < ActiveFedora::Base
belongs_to :library
end
library = Library.create
library.books.create
library.books.create
library.books.create
library.books.destroy_all
Deleting the Fedora object of a child without deleting its solr record causes an infinite loop when the parent collection is referenced.
I don't want to check this test in, because it hangs, even wrapped in a timeout()
block.
require 'spec_helper'
require 'timeout'
describe "fedora_solr_sync_issues" do
before :all do
class ParentThing < ActiveFedora::Base
has_many :things, :class_name=>'ChildThing', :property=>:is_part_of
end
class ChildThing < ActiveFedora::Base
belongs_to :parent, :class_name=>'ParentThing', :property=>:is_part_of
end
end
after :all do
Object.send(:remove_const, :ChildThing)
Object.send(:remove_const, :ParentThing)
end
let(:parent) { ParentThing.create }
subject { ChildThing.create :parent => parent }
it "should not go into an infinite loop" do
subject.inner_object.delete
parent.reload
Timeout::timeout(5) { parent.things.should == [] }
end
end
It's possible to instll active-fedora 5.6.2 with solrizer 3.0.0, however this causes an error. We should restrict solrizer to '~> 2.1.0'
gem 'solrizer', '~> 2.1.0'
This is just a question.
On this page https://github.com/projecthydra/active_fedora/wiki/Getting-Started:-Console-Tour there is a delete example that looks like this:
ActiveFedora::Base.find("hydrangea:fixture_mods_article1").delete
When I tried this inline-style delete, it kept creating new objects in place of the one I just deleted. I had break it up into two separate commands to work.. e.g.
x = ActiveFedora::Base.find("hydrangea:fixture_mods_article1").delete
x.delete
Is the previous, one-liner still valid?
If so, what might have been going on in my case?
If not, should I update the wiki to be the two-liner? Or is there a different way that is preferred?
Specifically: 'fedora-system:ContentModel-3.0', 'fedora-system:FedoraObject-3.0', 'fedora-system:ServiceDeployment-3.0', 'fedora-system:ServiceDefinition-3.0'
Shouldn't this return false? FYI: this is on 5.6.2. I haven't tested this in 6.x.
This ticket is a placeholder for UCSD work improving support for complex RDF content.
(ie. update_attributes)
All RDF properties accept hash arguments, allowing sub-hashes to cascade to children
params = {
myResource: {
topic: "Cosmology",
temporal: "16th Century",
personalName: {
fullName: "Jefferson, Thomas",
dateName: "1743-1826"
},
personalName: {
fullName: "Jefferson, Thomas",
dateName: "1743-1826"
},
corporateName: {
name: "University of California, San Diego.",
name: "University Library",
},
complexSubject: {
personalName: {
fullName: "Jeffersion, Thomas",
dateName: "1743-1826"
},
topic: "Presidency",
temporal: "1801-1809"
},
}
}
@resource = DamsResource.new()
@resource.attributes = (params[:myResource])
Note: NOT implementing update_attributes
because, due to the nature of RDF graphs, we cannot support updating existing nodes. You would need a full RDF graph in that case (predicates, URIs, etc.). This work is only supporting mass-setting of the graph and mass updating the graph from Hashes of properties and values (as opposted to URIs, predicates, and values).
** Not implementing computed properties at this time. **
ie.value of mads:authoritativeLabel element is computed based on the other stuff in the parent node.
Formula for specifying computed fields:
=
and <<
operators accept string, RDF node or a hash then create the necessary node for you according to the property definition/declaration=
and <<
operators apply string to a default node. If no default node is specified for the property, raises an error"Initializing ActiveFedora Rake environment. This should only be called when working within a _workign_ copy of the active-fedora code."
Update the documentation on ActiveFedora::DatastreamCollections and remove the "experimental" designation.
When you create a new datastream, it should not save anything just because it has a template. You should have to set a field first. Once you do that, then it should
Given I have a Page and a Book class
When the Page belongs_to a Book, with property :is_part_of
Then the Book's has_many relationship need not have the property :is_part_of
class Page
belongs_to :book, property: :is_part_of
end
class Book
has_many :pages
end
While the .first method is available for ActiveFedora objects, the .last method is not. At some point it must have been considered because it is an option on the .find method. See: https://github.com/projecthydra/active_fedora/blob/master/lib/active_fedora/relation.rb#L102
@flyingzumwalt said that perhaps this was just an oversight and I will submit a pull request to add this method.
> i = Item.create
# i now has DC and RELS-EXT in Fedora
> i.save
# i now also has descMetadata and rightsMetadata in Fedora
Formerly HYDRA-875
class Catalog < AF::Base
has_many :releases, :class_name=> "Album", :property=> :is_part_of
has_many :tracks, :class_name=> "Track", :property=> :is_part_of
end
Catalog#releases.send(:construct_query)
produces a query like: is_part_of_s:info:fedora/catalog:7"
which is the same as
Catalog#tracks.send(:construct_query)
=> is_part_of_s:info:fedora/catalog:7"
So Catalog#releases returns the same objects as Catalog#tracks.
The datastream should be loaded lazily
It appears that Rails generators are using different methods when updating:
Rails 3
@book = Book.find(params[:id])
@book.update_attributes(params[:book])
Rails 4
@book = Book.find(params[:id])
@book.update(params.book)
(Or something like this)
The ActiveFedora::Base.delegates keys are all symbols; However, if the key is accessed as a string then a NoMethodError is raised.
This is evident in Sufia in which the config has keys that are strings.
GenericFile.new.descMetadata.class.config
=> {"part_of"=>{"predicate"=>#<RDF::URI:0x3fc098fd16f8(http://purl.org/dc/terms/isPartOf)>}, "resource_type"=>{"predicate"=>#<RDF::URI:0x3fc098fd008c(http://purl.org/dc/terms/type)>, "type"=>:string, "behaviors"=>[:stored_searchable, :facetable]}, "title"=>{"predicate"=>#<RDF::URI:0x3fc09a7d8eb8(http://purl.org/dc/terms/title)>, "type"=>:string, "behaviors"=>[:stored_searchable]}, "creator"=>{"predicate"=>#<RDF::URI:0x3fc098fd4880(http://purl.org/dc/terms/creator)>, "type"=>:string, "behaviors"=>[:stored_searchable, :facetable]}, "contributor"=>{"predicate"=>#<RDF::URI:0x3fc098fd8ebc(http://purl.org/dc/terms/contributor)>, "type"=>:string, "behaviors"=>[:stored_searchable, :facetable]}, "description"=>{"predicate"=>#<RDF::URI:0x3fc09a7dd738(http://purl.org/dc/terms/description)>, "type"=>:text, "behaviors"=>[:stored_searchable]}, "tag"=>{"predicate"=>#<RDF::URI:0x3fc098fdcc9c(http://purl.org/dc/terms/relation)>, "type"=>:string, "behaviors"=>[:stored_searchable, :facetable]}, "rights"=>{"predicate"=>#<RDF::URI:0x3fc098fe02d4(http://purl.org/dc/terms/rights)>, "type"=>:string, "behaviors"=>[:stored_searchable]}, "publisher"=>{"predicate"=>#<RDF::URI:0x3fc098fe95b4(http://purl.org/dc/terms/publisher)>, "type"=>:string, "behaviors"=>[:stored_searchable, :facetable]}, "date_created"=>{"predicate"=>#<RDF::URI:0x3fc098fecdf4(http://purl.org/dc/terms/created)>, "type"=>:string, "behaviors"=>[:stored_searchable]}, "date_uploaded"=>{"predicate"=>#<RDF::URI:0x3fc09a7e1f68(http://purl.org/dc/terms/dateSubmitted)>, "type"=>:date, "behaviors"=>[:stored_sortable]}, "date_modified"=>{"predicate"=>#<RDF::URI:0x3fc09a7e0758(http://purl.org/dc/terms/modified)>, "type"=>:date, "behaviors"=>[:stored_sortable]}, "subject"=>{"predicate"=>#<RDF::URI:0x3fc098ff0a44(http://purl.org/dc/terms/subject)>, "type"=>:string, "behaviors"=>[:stored_searchable, :facetable]}, "language"=>{"predicate"=>#<RDF::URI:0x3fc098ff9cd4(http://purl.org/dc/terms/language)>, "type"=>:string, "behaviors"=>[:stored_searchable, :facetable]}, "identifier"=>{"predicate"=>#<RDF::URI:0x3fc098ff8528(http://purl.org/dc/terms/identifier)>, "type"=>:string, "behaviors"=>[:stored_searchable]}, "based_near"=>{"predicate"=>#<RDF::URI:0x3fc09c40c148(http://xmlns.com/foaf/0.1/based_near)>, "type"=>:string, "behaviors"=>[:stored_searchable, :facetable]}, "related_url"=>{"predicate"=>#<RDF::URI:0x3fc09c414e10(http://www.w3.org/2000/01/rdf-schema#seeAlso)>}}
In AF <7.0.0 when I delegate an accessor to a datastream, the model defaults to assuming that the attribute is multivalued. In a future major release, it would be nice to change the default to be single valued.
CURRENT:
delegate :title, to: 'descMetadata'
...
2.0.0p0 :002 > x.title = "A book in my library"
=> "A book in my library"
2.0.0p0 :003 > x.title
=> ["A book in my library"]
i.e. the delegated field is always treated as a multivalued array by default. This behavior can be fixed by adding the modifier unique: :true
, but the current behavior may be counter-intuitive to someone used to standard rails conventions
DESIRED:
delegate :title, to: 'descMetadata'
...
2.0.0p0 :002 > x.title = "A book in my library"
=> "A book in my library"
2.0.0p0 :003 > x.title
=> "A book in my library"
i.e. the default behavior for delegation is for the accessor to behave as a single value field.
OR
Consider moving this into OM since it's really a concern related to the interpretation of the XML datastream associated with the model and gets handled fine if you're not delegating to an OM datastream.
I have two models extending ActiveFedora::Base
, sharing a has_many
/ belongs_to
relationship, where the belongs_to
model will raise an error on #save!
if certain requirements aren't met.
Specifically, the
belongs_to
model includesSufia::GenericFile
and you must supply something to#apply_depositor_metadata
for it so save without error.
here is the has_many
model...
# models/rockband.rb
class Rockband < ActiveFedora::Base
has_many :rockstars, :property => :is_part_of, :inbound => true, :class_name => "Rockstar"
end
and here is the belongs_to
model...
# models/rockstar.rb
class Rockstar < ActiveFedora::Base
belongs_to :rockband, :property => :is_part_of, :class_name => "Rockband"
end
... and from the console...
# here we get a validation error, as expected...
> tommy_lee = Rockstar.new
> tommy_lee.save!
ActiveFedora::RecordInvalid: Validation failed: Rockstars must have a name! Duh!
# Here, the same validation error occurs, but nothing is raised.
# Just returns false.
> motley_crue = Rockband.create
> motley_crue.rockstars << Rockstar.new
false
e.g. label, state, mime type, etc, etc.
It only works for strings.
You can use Datastream#get_values instead.
Replace random namespaces with test:
This is a Rubydora issue, but I need a testing placeholder for a branch in ActiveFedora.
Given that we often do AF.find(pid, cast: true), we should assume that parameter. It would also tidy up the API and bring it closer inline to ActiveRecord.
Don't forget to deprecate the existing behavior of not casting unless specified
I stumbled upon this when my travis build for #156 began failing in places I had not touched.
The problem is that rdf-rdfxml has changed in some meaningful way from 1.0.1 to 1.0.2. To get the errors, change the gemspec from s.add_dependency("rdf-rdfxml", '1.0.1')
to s.add_dependency("rdf-rdfxml", '1.0.2')
PreservationEvent.find({:is_preservation_event_for_s => internal_uri}, {:sort => "event_date_time_dt asc"})
Worked in AF 5.0.0.pre11 but in 5.5.2 It causes this error:
RSolr::Error::Http: RSolr::Error::Http - 400 Bad Request
Error: undefined field order
The sort option is getting put into the query (q) parameter rather than its own parameter
Would it be possible to incorporate the ActiveFedora model generator as a registered ORM for the rails generate scaffold:
So rails generate scaffold Book --orm=active_fedora
Usage:
rails generate scaffold NAME [field[:type][:index] field[:type][:index]] [options]
Options:
[--skip-namespace] # Skip namespace (affects only isolated applications)
[--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9
-o, --orm=NAME # Orm to be invoked
# Default: active_record
We're getting these test failures using AF 5.x and Rubydora 1.4+. Should we:
a) pin AF 5.x to Rubydora < 1.3
b) find out what to backport from master
and try to apply it (and hope it doesn't REQUIRE Rubydora 1.4+, which I suspect it may..)
c) not care, because it seems like it's probably an edge case
Failures:
1) ActiveFedora::OmDatastream#changed? should not be changed if there are minor differences in whitespace
Failure/Error: obj.descMetadata.should_not be_changed
expected changed? to return false, got true
# ./spec/integration/om_datastream_spec.rb:38:in `block (3 levels) in <top (required)>'
2) ActiveFedora::OmDatastream.update_values should not be dirty after .update_values is saved
Failure/Error: @test_object.datastreams["descMetadata"].should_not be_changed
expected changed? to return false, got true
# ./spec/integration/om_datastream_spec.rb:106:in `block (3 levels) in <top (required)>'
Formerly HYDRA-852
validates :name, :uniqueness=>true
doesn't seem to work, though :presence=>true does.
The active_fedora:model generator should:
ActiveFedora::Base.find(conditions, :cast=>true)
adapts the response to its first declared CModel. Principle of Least Surprise would expect ActiveFedora.find(:first, :cast=>true)
and ActiveFedora.find(:all, :cast=>true)
to do the same, but they don't.
Formerly HYDRA-891
Broken test: rspec ./spec/integration/base_spec.rb:734
Blocked by this issue: sparklemotion/nokogiri#801
class Item < ActiveFedora::Base
has_many :components, :property => :is_part_of
end
class Component < ActiveFedora::Base
belongs_to :item, :property => :is_part_of
end
i = Item.create
c = Component.create
i.components << c
i.save!
c.delete
i.delete
This code results in:
Failure/Error: i.delete
RuntimeError:
# ./lib/active_fedora/persistence.rb:129:in `persist'
# ./lib/active_fedora/callbacks.rb:238:in `block in persist'
# ./lib/active_fedora/callbacks.rb:238:in `persist'
# ./lib/active_fedora/persistence.rb:125:in `update'
# ./lib/active_fedora/callbacks.rb:246:in `block in update'
# ./lib/active_fedora/callbacks.rb:246:in `update'
# ./lib/active_fedora/persistence.rb:13:in `save'
# ./lib/active_fedora/validations.rb:50:in `save'
# ./lib/active_fedora/persistence.rb:59:in `block (2 levels) in delete'
# ./lib/active_fedora/associations/association_proxy.rb:110:in `block in method_missing'
# ./lib/active_fedora/associations/association_proxy.rb:110:in `each'
# ./lib/active_fedora/associations/association_proxy.rb:110:in `method_missing'
# ./lib/active_fedora/persistence.rb:56:in `block in delete'
# ./lib/active_fedora/persistence.rb:55:in `each_pair'
# ./lib/active_fedora/persistence.rb:55:in `delete'
Introduced in 499e575
Basically, i.delete is trying to update the object 'c', which has already been removed. You can work around by reversing the order of the deletes or by calling #reload() on 'i' before deleting it.
There is an option to configure ActiveFedora::Base.solr_query_handler, but ActiveFedora::SolrService.query uses "standard"
Is that appropriate, or should we be using ActiveFedora::Base.solr_query_handler for :qt?
Also, to consider, each ActiveFedora::Base descendant may have a different config. Which would mean we'd need to pass the class in to the ActiveFedora::SolrService.query
Thoughts?
Given that I have a multi-value attribute "title" on an ActiveFedora::Base object.
When I set the "title" attribute with a string (i.e. "My Title")
Then I would expect the return value of the setter to be an Array (i.e. ["My Title"])
See below:
b = Book.new
b.title = "My Title"
=> ["My Title"]
Managed datastreams cause less load on Fedora.
We would leave RELS-EXT and DC defaulted to "X"
See: https://groups.google.com/d/msg/hydra-tech/g-64TekIjjw/U-DN7jxqOUoJ
The NomDatastream does not implement #update_indexed_attributes
A datastream declared via ActiveFedora::Base.has_metadata is expected to implement #update_indexed_attributes
Is there a specific expected interface that a Datastream should adhere to?
It appears the missing methods for NomDatastream are:
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.