Module: ActiveFedora::RelationshipsHelper::ClassMethods

Defined in:
lib/active_fedora/relationships_helper.rb

Instance Method Summary collapse

Instance Method Details

#bidirectional_named_relationship_query(pid, relationship_name, outbound_pids) ⇒ Object

Deprecated.

Please use #bidirectional_relationship_query instead.



882
883
884
885
# File 'lib/active_fedora/relationships_helper.rb', line 882

def bidirectional_named_relationship_query(pid,relationship_name,outbound_pids)
  logger.warn("Deprecation: bidirectional_named_relationship_query has been deprecated.  Please call bidirectional_relationship_query instead.")
  bidirectional_relationship_query(pid,relationship_name,outbound_pids)
end

#bidirectional_relationship_query(pid, relationship_name, outbound_pids) ⇒ String

Returns a solr query for retrieving objects specified in a bidirectional relationship. This method is mostly used by internal method calls. It usea of solr_fq value defined within a relationship to attach a query filter on top of just the predicate being used. Because it is static it needs the pids defined within RELS-EXT for the outbound relationship as well as the pid of the object for the inbound portion of the relationship. If you are calling this method directly to get the query you should use the ActiveFedora::SemanticNode.relationship_query instead or use the helper method [relationship_name]_query, i.e. method “bi_parts_query” for relationship “bi_parts”. This method would only be called directly if you had something like an array of outbound pids already in something like a solr document for object that has these relationships.

Examples:

Class SampleAFObjRelationshipFilterQuery < ActiveFedora::Base
  has_bidirectional_relationship "bi_series_parts", :has_part, :is_part_of, :solr_fq=>"level_t:series"
end
s = SampleAFObjRelationshipFilterQuery.new
obj = ActiveFedora::Base.new
s.bi_series_parts_append(obj)
s.pid
#=> "changeme:13025" 
obj.pid
#=> id:changeme:13026
s.bi_series_parts_query 
#=> "(id:changeme\\:13026 AND level_t:series) OR (is_part_of_s:info\\:fedora/changeme\\:13025 AND level_t:series)" 
SampleAFObjRelationshipFilterQuery.bidirectional_relationship_query(s.pid,"series_parents",["id:changeme:13026"])
#=> "(id:changeme\\:13026 AND level_t:series) OR (is_part_of_s:info\\:fedora/changeme\\:13025 AND level_t:series)" 

Parameters:

  • The (String)

    pid for the object that has these inbound relationships

  • The (String)

    name of the relationship defined in the model

  • An (Array)

    array of pids to include in the query

Returns:

  • (String)


789
790
791
792
793
794
795
796
797
# File 'lib/active_fedora/relationships_helper.rb', line 789

def bidirectional_relationship_query(pid,relationship_name,outbound_pids)
  outbound_query = outbound_relationship_query("#{relationship_name}_outbound",outbound_pids) 
  inbound_query = inbound_relationship_query(pid,"#{relationship_name}_inbound")
  query = outbound_query # use outbound_query by default
  if !inbound_query.empty?
    query << " OR (" + inbound_relationship_query(pid,"#{relationship_name}_inbound") + ")"
  end
  return query      
end

#create_bidirectional_named_relationship_methods(name, outbound_name) ⇒ Object

Deprecated.


864
865
866
867
# File 'lib/active_fedora/relationships_helper.rb', line 864

def create_bidirectional_named_relationship_methods(name,outbound_name)
  logger.warn("Deprecation: create_bidirectional_named_relationship_methods has been deprecated.  Please call create_bidirectional_relationship_name_methods instead.")
  create_bidirectional_relationship_name_methods(name,outbound_name)
end

#create_bidirectional_relationship_name_methods(name, outbound_name) ⇒ Object

** EXPERIMENTAL **

Similar to +create_relationship_name_methods+ except it is used when an ActiveFedora::Base model class
declares has_bidirectional_relationship.  we are merely creating an alias for outbound portion of bidirectional
@param [String] bidirectional relationship name
@param [String] outbound relationship method name associated with the bidirectional relationship ([bidirectional_name]_outbound)
@example
  has_bidirectional_relationship "members", :has_collection_member, :is_member_of_collection

  Method members_outbound_append and members_outbound_remove added
  This method will create members_append which does same thing as members_outbound_append
  and will create members_remove which does same thing as members_outbound_remove


659
660
661
662
663
664
# File 'lib/active_fedora/relationships_helper.rb', line 659

def create_bidirectional_relationship_name_methods(name,outbound_name)
  append_method_name = "#{name.to_s.downcase}_append"
  remove_method_name = "#{name.to_s.downcase}_remove"
  self.send(:define_method,:"#{append_method_name}") {|object| add_relationship_by_name(outbound_name,object)}
  self.send(:define_method,:"#{remove_method_name}") {|object| remove_relationship_by_name(outbound_name,object)}
end

#create_named_relationship_methods(name) ⇒ Object

Deprecated.

Please use #create_relationship_name_methods instead.



858
859
860
861
# File 'lib/active_fedora/relationships_helper.rb', line 858

def create_named_relationship_methods(name)
  logger.warn("Deprecation: create_named_relationship_methods has been deprecated.  Please call create_relationship_name_methods instead.")
  create_relationship_name_methods(name)
end

#create_relationship_name_methods(name) ⇒ Object

** EXPERIMENTAL **

Used in has_relationship call to create dynamic helper methods to append and remove objects to and from a relationship

Examples:

For the following relationship

has_relationship "audio_records", :has_part, :type=>AudioRecord

Methods audio_records_append and audio_records_remove are created.
Boths methods take an object that is kind_of? ActiveFedora::Base as a parameter

Parameters:

  • relationship (String)

    name to create helper methods for



641
642
643
644
645
646
# File 'lib/active_fedora/relationships_helper.rb', line 641

def create_relationship_name_methods(name)
  append_method_name = "#{name.to_s.downcase}_append"
  remove_method_name = "#{name.to_s.downcase}_remove"
  self.send(:define_method,:"#{append_method_name}") {|object| add_relationship_by_name(name,object)}
  self.send(:define_method,:"#{remove_method_name}") {|object| remove_relationship_by_name(name,object)}
end

#inbound_named_relationship_query(pid, relationship_name) ⇒ Object

Deprecated.

Please use #inbound_relationship_query instead.



876
877
878
879
# File 'lib/active_fedora/relationships_helper.rb', line 876

def inbound_named_relationship_query(pid,relationship_name)
  logger.warn("Deprecation: inbound_named_relationship_query has been deprecated.  Please call inbound_relationship_query instead.")
  inbound_relationship_query(pid,relationship_name)
end

#inbound_relationship_query(pid, relationship_name) ⇒ String

Returns a solr query for retrieving objects specified in an inbound relationship. This method is mostly used by internal method calls. It utilizes any solr_fq value defined within a relationship to attach a query filter on top of just the predicate being used. Because it is static it needs the pid of the object that has the inbound relationships passed in. If you are calling this method directly to get the query you should use the ActiveFedora::SemanticNode.relationship_query instead or use the helper method [relationship_name]_query, i.e. method “parts_query” for relationship “parts”. This method would only be called directly if you were working only with Solr and already had the pid for the object in something like a solr document.

Examples:

Class SampleAFObjRelationshipFilterQuery < ActiveFedora::Base
  #returns all parts
  has_relationship "parts", :is_part_of, :inbound=>true
  #returns only parts that have level to "series"
  has_relationship "series_parts", :is_part_of, :inbound=>true, :solr_fq=>"level_t:series"
end
s = SampleAFObjRelationshipFilterQuery.new
s.pid 
#=> id:changeme:13020
s.series_parts_query
#=> "is_part_of_s:info\\:fedora/changeme\\:13021 AND level_t:series"
SampleAFObjRelationshipFilterQuery.inbound_relationship_query(s.pid,"series_parts")
#=> "is_part_of_s:info\\:fedora/changeme\\:13021 AND level_t:series"

Parameters:

  • The (String)

    pid for the object that has these inbound relationships

  • The (String)

    name of the relationship defined in the model

Returns:

  • (String)


742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
# File 'lib/active_fedora/relationships_helper.rb', line 742

def inbound_relationship_query(pid,relationship_name)
  query = ""
  subject = :inbound
  if relationships_desc.has_key?(subject) && relationships_desc[subject].has_key?(relationship_name)
    predicate = relationships_desc[subject][relationship_name][:predicate]
    internal_uri = "info:fedora/#{pid}"
    escaped_uri = internal_uri.gsub(/(:)/, '\\:')
    query = "#{predicate}_s:#{escaped_uri}" 
    if relationships_desc.has_key?(subject) && relationships_desc[subject].has_key?(relationship_name) && relationships_desc[subject][relationship_name].has_key?(:solr_fq)
      solr_fq = relationships_desc[subject][relationship_name][:solr_fq]
      query << " AND " unless query.empty?
      query << solr_fq
    end
  end
  query
end

#is_bidirectional_relationship?(relationship_name) ⇒ Boolean

Tests if the relationship name passed is in bidirectional

Parameters:

  • relationship (String)

    name to test

Returns:

  • (Boolean)


625
626
627
# File 'lib/active_fedora/relationships_helper.rb', line 625

def is_bidirectional_relationship?(relationship_name)
  (relationships_desc.has_key?(:self)&&relationships_desc.has_key?(:inbound)&&relationships_desc[:self].has_key?("#{relationship_name}_outbound") && relationships_desc[:inbound].has_key?("#{relationship_name}_inbound")) 
end

#named_predicate_exists_with_different_name?(subject, name, predicate) ⇒ Boolean

Returns:

  • (Boolean)


888
889
890
891
# File 'lib/active_fedora/relationships_helper.rb', line 888

def named_predicate_exists_with_different_name?(subject,name,predicate)
  logger.warn("Deprecation: named_predicate_exists_with_different_name? has been deprecated.  Please call predicate_exists_with_different_relationship_name? instead.")
  predicate_exists_with_different_relationship_name?(subject,name,predicate)
end

#named_relationships_descObject

Deprecated.

Please use #relationships_desc instead.



840
841
842
843
# File 'lib/active_fedora/relationships_helper.rb', line 840

def named_relationships_desc
  logger.warn("Deprecation: named_relationships_desc has been deprecated.  Please call relationships_desc instead.")
  relationships_desc
end

#outbound_named_relationship_query(relationship_name, outbound_pids) ⇒ Object

Deprecated.

Please use #outbound_relationship_query instead.



870
871
872
873
# File 'lib/active_fedora/relationships_helper.rb', line 870

def outbound_named_relationship_query(relationship_name,outbound_pids)
  logger.warn("Deprecation: outbound_named_relationship_query has been deprecated.  Please call outbound_relationship_query instead.")
  outbound_relationship_query(relationship_name,outbound_pids)
end

#outbound_relationship_query(relationship_name, outbound_pids) ⇒ String

Returns a solr query for retrieving objects specified in an outbound relationship. This method is mostly used by internal method calls. It utilizes any solr_fq value defined within a relationship to attach a query filter when querying solr on top of just the predicate being used. Because it is static it needs the pids defined within RELS-EXT for this relationship to be passed in. If you are calling this method directly to get the query you should use the ActiveFedora::SemanticNode.relationship_query instead or use the helper method [relationship_name]_query, i.e. method “parts_query” for relationship “parts”. This method would only be called directly if you had something like an array of outbound pids already in something like a solr document for object that has these relationships.

Examples:

Class SampleAFObjRelationshipFilterQuery < ActiveFedora::Base
  #points to all parents linked via is_member_of
  has_relationship "parents", :is_member_of
  #returns only parents that have a level value set to "series"
  has_relationship "series_parents", :is_member_of, :solr_fq=>"level_t:series"
end
s = SampleAFObjRelationshipFilterQuery.new
obj = ActiveFedora::Base.new
s.series_parents_append(obj)
s.series_parents_query 
#=> "(id:changeme\\:13020 AND level_t:series)" 
SampleAFObjRelationshipFilterQuery.outbound_relationship_query("series_parents",["id:changeme:13020"])
#=> "(id:changeme\\:13020 AND level_t:series)" 

Parameters:

  • The (String)

    name of the relationship defined in the model

  • An (Array)

    array of pids to include in the query

Returns:

  • (String)


694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
# File 'lib/active_fedora/relationships_helper.rb', line 694

def outbound_relationship_query(relationship_name,outbound_pids)
  query = ActiveFedora::SolrService.construct_query_for_pids(outbound_pids)
  subject = :self
  if relationships_desc.has_key?(subject) && relationships_desc[subject].has_key?(relationship_name) && relationships_desc[subject][relationship_name].has_key?(:solr_fq)
    solr_fq = relationships_desc[subject][relationship_name][:solr_fq]
    unless query.empty?
      #substitute in the filter query for each pid so that it is applied to each in the query
      query_parts = query.split(/OR/)
      query = ""
      query_parts.each_with_index do |query_part,index|
        query_part.strip!
        query << " OR " if index > 0
        query << "(#{query_part} AND #{solr_fq})"
      end
    else
      query = solr_fq
    end
  end
  query
end

#predicate_exists_with_different_relationship_name?(subject, name, predicate) ⇒ Boolean

** EXPERIMENTAL **

Check to make sure a subject,name, and predicate triple does not already exist with the same subject but different name. This method is used to ensure conflicting has_relationship calls are not made because predicates cannot be reused across relationship names. Otherwise, the mapping of relationship name to predicate in RELS-EXT would be broken.

Parameters:

  • subject (Symbol)

    to check (:self or :inbound)

  • relationship (String)

    name

  • symbol (Symbol)

    for Fedora relationship ontology predicate

Returns:

  • (Boolean)


817
818
819
820
821
822
823
824
# File 'lib/active_fedora/relationships_helper.rb', line 817

def predicate_exists_with_different_relationship_name?(subject,name,predicate)
  if relationships_desc.has_key?(subject)
    relationships_desc[subject].each_pair do |existing_name, args|
      return true if !args[:predicate].nil? && args[:predicate] == predicate && existing_name != name 
    end
  end
  return false
end

#register_named_relationship(subject, name, predicate, opts) ⇒ Object

Deprecated.

Please use #register_relationship_desc instead.



852
853
854
855
# File 'lib/active_fedora/relationships_helper.rb', line 852

def register_named_relationship(subject, name, predicate, opts)
  logger.warn("Deprecation: register_named_relationship has been deprecated.  Please call register_relationship_desc instead.")
  register_relationship_desc(subject, name, predicate, opts)
end

#register_named_subject(subject) ⇒ Object

Deprecated.


846
847
848
849
# File 'lib/active_fedora/relationships_helper.rb', line 846

def register_named_subject(subject)
  logger.warn("Deprecation: register_named_subject has been deprecated.  Please call register_relationship_desc_subject instead.")
  register_relationship_desc_subject(subject)
end

#register_relationship_desc(subject, name, predicate, opts = {}) ⇒ Object

** EXPERIMENTAL **

Internal method that adds relationship name and predicate pair to either an outbound (:self) or inbound (:inbound) relationship types. Refer to ActiveFedora::SemanticNode.has_relationship for information on what metadata will be persisted.

Parameters:

  • Subject (Symbol)

    name to register

  • Name (String)

    of relationship being registered

  • Fedora (Symbol)

    ontology predicate to use

  • Any (Hash)

    options passed to has_relationship such as :type, :solr_fq, etc.



616
617
618
619
620
# File 'lib/active_fedora/relationships_helper.rb', line 616

def register_relationship_desc(subject, name, predicate, opts={})
  register_relationship_desc_subject(subject)
  opts.merge!({:predicate=>predicate})
  relationships_desc[subject][name] = opts
end

#register_relationship_desc_subject(subject) ⇒ Object

** EXPERIMENTAL **

Internal method that ensures a relationship subject such as :self and :inbound exist within the relationships_desc hash tracking relationships metadata.

Parameters:

  • Subject (Symbol)

    name to register (will probably be something like :self or :inbound)



602
603
604
605
606
# File 'lib/active_fedora/relationships_helper.rb', line 602

def register_relationship_desc_subject(subject)
  unless relationships_desc.has_key?(subject) 
    relationships_desc[subject] = {} 
  end
end

#relationship_has_solr_filter_query?(subject, relationship_name) ⇒ Boolean

Check if a relationship has any solr query filters defined by has_relationship call

Parameters:

  • subject (Symbol)

    to use such as :self or :inbound

  • relationship (String)

    name

Returns:

  • (Boolean)

    true if the relationship has a query filter defined



803
804
805
# File 'lib/active_fedora/relationships_helper.rb', line 803

def relationship_has_solr_filter_query?(subject, relationship_name)
  relationships_desc.has_key?(subject) && relationships_desc[subject].has_key?(relationship_name) && relationships_desc[subject][relationship_name].has_key?(:solr_fq)
end

#relationships_descHash

** EXPERIMENTAL **

Return hash that persists relationship metadata defined by has_relationship calls. If you implement a child class of ActiveFedora::Base it will inherit the relationship descriptions defined there by merging in the class instance variable values. It will also do this for any level of ancestors.

Examples:

For the following relationship

has_relationship "audio_records", :has_part, :type=>AudioRecord

Results in the following returned by relationships_desc
{:self=>{"audio_records"=>{:type=>AudioRecord, :singular=>nil, :predicate=>:has_part, :inbound=>false}}}

Returns:

  • (Hash)

    Hash of relationship subject (:self or :inbound) mapped to nested hashs of each relationship name mapped to another hash relationship options



570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
# File 'lib/active_fedora/relationships_helper.rb', line 570

def relationships_desc
  #get any relationship descriptions from superclasses
  if @class_relationships_desc.nil?
    @class_relationships_desc ||= Hash[:self => {}]

    #get super classes
    super_klasses = []
    #insert in reverse order so the child overwrites anything in parent
    super_klass = self.superclass
    while !super_klass.nil?
      super_klasses.insert(0,super_klass)
      super_klass = super_klass.superclass
    end
  
    super_klasses.each do |super_klass|
      if super_klass.respond_to?(:relationships_desc)
        super_rels = super_klass.relationships_desc
        super_rels.each_pair do |subject,rels|
          @class_relationships_desc[subject] = {} unless @class_relationships_desc.has_key?(subject)
          @class_relationships_desc[subject].merge!(rels)
        end
      end
    end
  end
  @class_relationships_desc
end