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.



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

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)


784
785
786
787
788
789
790
791
792
# File 'lib/active_fedora/relationships_helper.rb', line 784

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.


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

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


654
655
656
657
658
659
# File 'lib/active_fedora/relationships_helper.rb', line 654

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.



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

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



636
637
638
639
640
641
# File 'lib/active_fedora/relationships_helper.rb', line 636

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.



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

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)


737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
# File 'lib/active_fedora/relationships_helper.rb', line 737

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)


620
621
622
# File 'lib/active_fedora/relationships_helper.rb', line 620

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)


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

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.



835
836
837
838
# File 'lib/active_fedora/relationships_helper.rb', line 835

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.



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

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)


689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
# File 'lib/active_fedora/relationships_helper.rb', line 689

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)


812
813
814
815
816
817
818
819
# File 'lib/active_fedora/relationships_helper.rb', line 812

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.



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

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.


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

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.



611
612
613
614
615
# File 'lib/active_fedora/relationships_helper.rb', line 611

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)



597
598
599
600
601
# File 'lib/active_fedora/relationships_helper.rb', line 597

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



798
799
800
# File 'lib/active_fedora/relationships_helper.rb', line 798

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



565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
# File 'lib/active_fedora/relationships_helper.rb', line 565

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