Module: ActiveFedora::SemanticNode::ClassMethods
- Defined in:
- lib/active_fedora/semantic_node.rb
Instance Method Summary collapse
-
#create_bidirectional_relationship_finders(name, outbound_predicate, inbound_predicate, opts = {}) ⇒ Object
Generates relationship finders for predicates that point in both directions and registers predicate relationships for each direction.
- #create_inbound_relationship_finders(name, predicate, opts = {}) ⇒ Object
- #create_outbound_relationship_finders(name, predicate, opts = {}) ⇒ Object
- #default_predicate_namespace ⇒ Object
- #find_predicate(predicate) ⇒ Object
-
#has_bidirectional_relationship(name, outbound_predicate, inbound_predicate, opts = {}) ⇒ Object
Generates relationship finders for predicates that point in both directions.
-
#has_relationship(name, predicate, opts = {}) ⇒ Object
Allows for a relationship to be treated like any other attribute of a model class.
- #predicate_config ⇒ Object
-
#predicate_lookup(predicate, namespace = "info:fedora/fedora-system:def/relations-external#") ⇒ Object
If predicate is a symbol, looks up the predicate in the predicate_mappings If predicate is not a Symbol, returns the predicate untouched.
- #predicate_mappings ⇒ Object
- #register_predicate(subject, predicate) ⇒ Object
- #register_subject(subject) ⇒ Object
-
#relationships ⇒ Object
relationships are tracked as a hash of structure.
-
#relationships_to_rels_ext(pid, relationships = self.relationships) ⇒ Object
Creates a RELS-EXT datastream for insertion into a Fedora Object Note: This method is implemented on SemanticNode instead of RelsExtDatastream because SemanticNode contains the relationships array.
Instance Method Details
#create_bidirectional_relationship_finders(name, outbound_predicate, inbound_predicate, opts = {}) ⇒ Object
Generates relationship finders for predicates that point in both directions and registers predicate relationships for each direction.
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
# File 'lib/active_fedora/semantic_node.rb', line 340 def create_bidirectional_relationship_finders(name, outbound_predicate, inbound_predicate, opts={}) inbound_method_name = name.to_s+"_inbound" outbound_method_name = name.to_s+"_outbound" has_relationship(outbound_method_name, outbound_predicate, opts) has_relationship(inbound_method_name, inbound_predicate, opts.merge!(:inbound=>true)) #create methods that mirror the outbound append and remove with our bidirectional name, assume just add and remove locally create_bidirectional_relationship_name_methods(name,outbound_method_name) class_eval <<-END def #{name}(opts={}) opts = {:rows=>25}.merge(opts) if opts[:response_format] == :solr || opts[:response_format] == :load_from_solr outbound_id_array = [] predicate = outbound_relationship_predicates["#{name}_outbound"] if !outbound_relationships[predicate].nil? outbound_relationships[predicate].each do |rel| outbound_id_array << rel.gsub("info:fedora/", "") end end #outbound_id_array = #{outbound_method_name}(:response_format=>:id_array) query = self.class.bidirectional_relationship_query(self.pid,"#{name}",outbound_id_array) solr_result = SolrService.instance.conn.query(query, :rows=>opts[:rows]) if opts[:response_format] == :solr return solr_result elsif opts[:response_format] == :load_from_solr || self.load_from_solr return ActiveFedora::SolrService.reify_solr_results(solr_result,{:load_from_solr=>true}) else return ActiveFedora::SolrService.reify_solr_results(solr_result) end else ary = #{inbound_method_name}(opts) + #{outbound_method_name}(opts) return ary.uniq end end def #{name}_ids #{name}(:response_format => :id_array) end def #{name}_from_solr #{name}(:response_format => :load_from_solr) end def #{name}_query relationship_query("#{name}") end END end |
#create_inbound_relationship_finders(name, predicate, opts = {}) ⇒ Object
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/active_fedora/semantic_node.rb', line 257 def create_inbound_relationship_finders(name, predicate, opts = {}) class_eval <<-END def #{name}(opts={}) opts = {:rows=>25}.merge(opts) query = self.class.inbound_relationship_query(self.pid,"#{name}") return [] if query.empty? solr_result = SolrService.instance.conn.query(query, :rows=>opts[:rows]) if opts[:response_format] == :solr return solr_result else if opts[:response_format] == :id_array id_array = [] solr_result.hits.each do |hit| id_array << hit[SOLR_DOCUMENT_ID] end return id_array elsif opts[:response_format] == :load_from_solr || self.load_from_solr return ActiveFedora::SolrService.reify_solr_results(solr_result,{:load_from_solr=>true}) else return ActiveFedora::SolrService.reify_solr_results(solr_result) end end end def #{name}_ids #{name}(:response_format => :id_array) end def #{name}_from_solr #{name}(:response_format => :load_from_solr) end def #{name}_query relationship_query("#{name}") end END end |
#create_outbound_relationship_finders(name, predicate, opts = {}) ⇒ Object
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/active_fedora/semantic_node.rb', line 292 def create_outbound_relationship_finders(name, predicate, opts = {}) class_eval <<-END def #{name}(opts={}) id_array = [] if !outbound_relationships[#{predicate.inspect}].nil? outbound_relationships[#{predicate.inspect}].each do |rel| id_array << rel.gsub("info:fedora/", "") end end if opts[:response_format] == :id_array && !self.class.relationship_has_solr_filter_query?(:self,"#{name}") return id_array else query = self.class.outbound_relationship_query("#{name}",id_array) solr_result = SolrService.instance.conn.query(query) if opts[:response_format] == :solr return solr_result elsif opts[:response_format] == :id_array id_array = [] solr_result.hits.each do |hit| id_array << hit[SOLR_DOCUMENT_ID] end return id_array elsif opts[:response_format] == :load_from_solr || self.load_from_solr return ActiveFedora::SolrService.reify_solr_results(solr_result,{:load_from_solr=>true}) else return ActiveFedora::SolrService.reify_solr_results(solr_result) end end end def #{name}_ids #{name}(:response_format => :id_array) end def #{name}_from_solr #{name}(:response_format => :load_from_solr) end def #{name}_query relationship_query("#{name}") end END end |
#default_predicate_namespace ⇒ Object
456 457 458 |
# File 'lib/active_fedora/semantic_node.rb', line 456 def default_predicate_namespace predicate_config[:default_namespace] end |
#find_predicate(predicate) ⇒ Object
460 461 462 463 464 465 466 467 |
# File 'lib/active_fedora/semantic_node.rb', line 460 def find_predicate(predicate) predicate_mappings.each do |namespace,predicates| if predicates.fetch(predicate,nil) return predicates[predicate], namespace end end raise ActiveFedora::UnregisteredPredicateError end |
#has_bidirectional_relationship(name, outbound_predicate, inbound_predicate, opts = {}) ⇒ Object
Generates relationship finders for predicates that point in both directions
Example:
has_bidirectional_relationship("parts", :has_part, :is_part_of)
will create three instance methods: parts_outbound, and parts_inbound and parts the inbound and outbound methods are the same that would result from calling create_inbound_relationship_finders and create_outbound_relationship_finders The third method combines the results of both and handles generating appropriate solr queries where necessary.
253 254 255 |
# File 'lib/active_fedora/semantic_node.rb', line 253 def has_bidirectional_relationship(name, outbound_predicate, inbound_predicate, opts={}) create_bidirectional_relationship_finders(name, outbound_predicate, inbound_predicate, opts) end |
#has_relationship(name, predicate, opts = {}) ⇒ Object
Allows for a relationship to be treated like any other attribute of a model class. You define relationships in your model class using this method. You then have access to several helper methods to list, append, and remove objects from the list of relationships.
Examples to define two relationships
class AudioRecord < ActiveFedora::Base
has_relationship "oral_history", :has_part, :inbound=>true, :type=>OralHistory
# returns all similar audio
has_relationship "similar_audio", :has_part, :type=>AudioRecord
#returns only similar audio with format wav
has_relationship "similar_audio_wav", :has_part, :solr_fq=>"format_t:wav"
The first two parameters are required:
name: relationship name
predicate: predicate for the relationship
opts:
possible parameters
:inbound => if true loads an external relationship via Solr (defaults to false)
:type => The type of model to use when instantiated an object from the pid in this relationship (defaults to ActiveFedora::Base)
:solr_fq => Define a solr query here if you want to filter out some objects in your relationship (must be a properly formatted solr query)
If inbound is true it expects the relationship to be defined by another object’s RELS-EXT and to load that relationship from Solr. Otherwise, if inbound is true the relationship is stored in this object’s RELS-EXT datastream
Word of caution - The same predicate may not be used twice for two inbound or two outbound relationships. However, it may be used twice if one is inbound and one is outbound as shown in the example above. A full list of possible predicates are defined by predicate_mappings
For the oral_history relationship in the example above the following helper methods are created:
oral_history: returns array of OralHistory objects that have this AudioRecord with predicate :has_part
oral_history_ids: Return array of pids for OralHistory objects that have this AudioRecord with predicate :has_part
oral_history_query: Return solr query that can be used to retrieve related objects as solr documents
For the outbound relationship “similar_audio” there are two additional methods to append and remove objects from that relationship since it is managed internally:
similar_audio: Return array of AudioRecord objects that have been added to similar_audio relationship
similar_audio_ids: Return array of AudioRecord object pids that have been added to similar_audio relationship
similar_audio_query: Return solr query that can be used to retrieve related objects as solr documents
similar_audio_append: Add an AudioRecord object to the similar_audio relationship
similar_audio_remove: Remove an AudioRecord from the similar_audio relationship
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/active_fedora/semantic_node.rb', line 222 def has_relationship(name, predicate, opts = {}) opts = {:singular => nil, :inbound => false}.merge(opts) if opts[:inbound] == true #raise "Duplicate use of predicate for inbound relationship name not allowed" if predicate_exists_with_different_relationship_name?(:inbound,name,predicate) register_relationship_desc(:inbound, name, predicate, opts) register_predicate(:inbound, predicate) create_inbound_relationship_finders(name, predicate, opts) else #raise "Duplicate use of predicate for outbound relationship name not allowed" if predicate_exists_with_different_relationship_name?(:self,name,predicate) register_relationship_desc(:self, name, predicate, opts) register_predicate(:self, predicate) create_relationship_name_methods(name) create_outbound_relationship_finders(name, predicate, opts) end end |
#predicate_config ⇒ Object
448 449 450 |
# File 'lib/active_fedora/semantic_node.rb', line 448 def predicate_config @@predicate_config ||= YAML::load(File.open(ActiveFedora.predicate_config)) if File.exist?(ActiveFedora.predicate_config) end |
#predicate_lookup(predicate, namespace = "info:fedora/fedora-system:def/relations-external#") ⇒ Object
If predicate is a symbol, looks up the predicate in the predicate_mappings If predicate is not a Symbol, returns the predicate untouched
437 438 439 440 441 442 443 444 445 446 |
# File 'lib/active_fedora/semantic_node.rb', line 437 def predicate_lookup(predicate,namespace="info:fedora/fedora-system:def/relations-external#") if predicate.class == Symbol if predicate_mappings[namespace].has_key?(predicate) return predicate_mappings[namespace][predicate] else raise ActiveFedora::UnregisteredPredicateError end end return predicate end |
#predicate_mappings ⇒ Object
452 453 454 |
# File 'lib/active_fedora/semantic_node.rb', line 452 def predicate_mappings predicate_config[:predicate_mapping] end |
#register_predicate(subject, predicate) ⇒ Object
402 403 404 405 406 407 |
# File 'lib/active_fedora/semantic_node.rb', line 402 def register_predicate(subject, predicate) register_subject(subject) if !relationships[subject].has_key?(predicate) relationships[subject][predicate] = [] end end |
#register_subject(subject) ⇒ Object
396 397 398 399 400 |
# File 'lib/active_fedora/semantic_node.rb', line 396 def register_subject(subject) if !relationships.has_key?(subject) relationships[subject] = {} end end |
#relationships ⇒ Object
relationships are tracked as a hash of structure
391 392 393 |
# File 'lib/active_fedora/semantic_node.rb', line 391 def relationships @class_relationships ||= Hash[:self => {}] end |
#relationships_to_rels_ext(pid, relationships = self.relationships) ⇒ Object
Creates a RELS-EXT datastream for insertion into a Fedora Object Note: This method is implemented on SemanticNode instead of RelsExtDatastream because SemanticNode contains the relationships array
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 |
# File 'lib/active_fedora/semantic_node.rb', line 415 def relationships_to_rels_ext(pid, relationships=self.relationships) starter_xml = <<-EOL <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="info:fedora/#{pid}"> </rdf:Description> </rdf:RDF> EOL xml = REXML::Document.new(starter_xml) # Iterate through the hash of predicates, adding an element to the RELS-EXT for each "object" in the predicate's corresponding array. self.outbound_relationships.each do |predicate, targets_array| targets_array.each do |target| #puts ". #{predicate} #{target}" xml.root.elements["rdf:Description"].add_element(predicate_lookup(predicate), {"xmlns" => "info:fedora/fedora-system:def/relations-external#", "rdf:resource"=>target}) end end xml.to_s end |