Module: ActiveFedora::Relationships

Extended by:
ActiveSupport::Concern, Deprecation
Defined in:
lib/active_fedora/relationships.rb

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#add_relationship_by_name(name, object) ⇒ Boolean

Add an outbound relationship for given relationship name See ActiveFedora::SemanticNode::ClassMethods.has_relationship

Parameters:

  • Name (String)

    of relationship

  • object (ActiveFedora::Base)

    to add to the relationship (expects ActvieFedora::Base to be an ancestor)

Returns:

  • (Boolean)

    returns true if add operation successful



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/active_fedora/relationships.rb', line 246

def add_relationship_by_name(name, object)
  Deprecation.silence(ActiveFedora::Relationships) do
  if is_relationship_name?(name,true)
    if relationships_desc[:self][name].has_key?(:type)
      klass = class_from_name(relationships_desc[:self][name][:type])
      unless klass.nil?
        (assert_conforms_to 'object', object, klass)
      end
    end
    add_relationship(outbound_relationship_predicates[name],object)
  else
    false
  end
  end
end

#assert_conforms_to(name, object, model_class) ⇒ Object

Throws an assertion error if conforms_to? returns false for object and model_class

Parameters:

  • Name (String)

    of object (just label for output)

  • Expects (ActiveFedora::Base)

    to be an object that has ActiveFedora::Base as an ancestor of its class

  • The (Class)

    model class used in conforms_to? check on object



132
133
134
# File 'lib/active_fedora/relationships.rb', line 132

def assert_conforms_to(name, object, model_class)
  raise "Assertion failure: #{name}: #{object.pid} does not have model #{model_class}, it has model #{relationships[:self][:has_model]}" unless object.conforms_to?(model_class)
end

#class_from_name(name) ⇒ Class

Returns a Class symbol for the given string for the class name

Parameters:

  • the (String)

    class name as a string

Returns:

  • (Class)

    the class as a Class object



141
142
143
144
145
# File 'lib/active_fedora/relationships.rb', line 141

def class_from_name(name)
  klass = name.to_s.split('::').inject(Kernel) {|scope, const_name| 
  scope.const_get(const_name)}
  (!klass.nil? && klass.is_a?(::Class)) ? klass : nil
end

#find_relationship_by_name(name) ⇒ Array

Deprecated.

find_relationship_by_name will be removed in active-fedora 6.0

Return array of objects for a given relationship name

Parameters:

  • Name (String)

    of relationship to find

Returns:

  • (Array)

    Returns array of objects linked via the relationship name given



13
14
15
16
17
18
19
20
21
22
# File 'lib/active_fedora/relationships.rb', line 13

def find_relationship_by_name(name)
  rels = nil
  if inbound_relationship_names.include?(name)
    rels = relationships_by_name(false)[:inbound][name]
  elsif outbound_relationship_names.include?(name)
    rels = relationships_by_name[:self][name]
  end
  rels = [] if rels.nil?
  return rels
end

#inbound_relationship_namesArray

Return array of relationship names for all inbound relationships (coming from other objects’ RELS-EXT and Solr)

Returns:

  • (Array)

    of inbound relationship names for relationships declared via has_relationship in the class



26
27
28
# File 'lib/active_fedora/relationships.rb', line 26

def inbound_relationship_names
    relationships_desc.has_key?(:inbound) ? relationships_desc[:inbound].keys : []
end

#inbound_relationships_by_nameHash

Return hash of relationships_by_name defined within other objects’ RELS-EXT It returns a hash of relationship name to arrays of objects. It requeries solr each time this method is called.

Returns:

  • (Hash)

    Return hash of each relationship name mapped to an Array of objects linked to this object via inbound relationships



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/active_fedora/relationships.rb', line 34

def inbound_relationships_by_name
  rels = {}
  if relationships_desc.has_key?(:inbound)&&!relationships_desc[:inbound].empty?()
    inbound_rels = inbound_relationships
  
    if relationship_predicates.has_key?(:inbound)
      relationship_predicates[:inbound].each do |name, predicate|
        rels[name] = inbound_rels.has_key?(predicate) ? inbound_rels[predicate] : []
      end
    end
  end
  return rels
end

#is_relationship_name?(name, outbound_only = true) ⇒ Boolean

Returns true if the given relationship name is a relationship

Parameters:

  • Name (String)

    of relationship

  • If (Boolean)

    false checks inbound relationships as well (defaults to true)

Returns:

  • (Boolean)


156
157
158
159
160
161
162
163
164
# File 'lib/active_fedora/relationships.rb', line 156

def is_relationship_name?(name, outbound_only=true)
  Deprecation.silence(ActiveFedora::Relationships) do
  if outbound_only
    outbound_relationship_names.include?(name)
  else
    (outbound_relationship_names.include?(name)||inbound_relationship_names.include?(name))
  end
  end
end

#load_bidirectional(name, inbound_method_name, outbound_method_name, opts) ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/active_fedora/relationships.rb', line 192

def load_bidirectional(name, inbound_method_name, outbound_method_name, opts) 
    opts = {:rows=>25}.merge(opts)
    if opts[:response_format] == :solr || opts[:response_format] == :load_from_solr
      predicate = outbound_relationship_predicates["#{name}_outbound"]
      outbound_id_array = ids_for_outbound(predicate)
      query = self.class.bidirectional_relationship_query(self.pid,"#{name}",outbound_id_array)
      solr_result = SolrService.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 = send(inbound_method_name,opts) + send(outbound_method_name, opts)
      return ary.uniq
    end
end

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



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/active_fedora/relationships.rb', line 167

def load_inbound_relationship(name, predicate, opts={})
  opts = {:rows=>25}.merge(opts)
  query = self.class.inbound_relationship_query(self.pid,"#{name}")
  return [] if query.empty?
  if opts[:response_format] == :solr
    solr_result = SolrService.query query, :raw=>true, :rows=>opts[:rows]
    return solr_result
  else
    solr_result = SolrService.query(query, :rows=>opts[:rows]) 
    if opts[:response_format] == :id_array
      id_array = []
      solr_result.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

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



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/active_fedora/relationships.rb', line 213

def load_outbound_relationship(name, predicate, opts={})
  id_array = ids_for_outbound(predicate)
  if opts[:response_format] == :id_array  && !self.relationship_has_solr_filter_query?(:self,"#{name}")
    return id_array
  else
    query = self.class.outbound_relationship_query(name,id_array)
    solr_result = SolrService.query(query)
    if opts[:response_format] == :solr
      return solr_result
    elsif opts[:response_format] == :id_array
      return solr_result.map {|hit| hit[SOLR_DOCUMENT_ID] }
    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

#outbound_relationship_namesArray

Return array of relationship names for all outbound relationships (coming from this object’s RELS-EXT)

Returns:

  • (Array)

    of outbound relationship names for relationships declared via has_relationship in the class



149
150
151
# File 'lib/active_fedora/relationships.rb', line 149

def outbound_relationship_names
    relationships_desc.has_key?(:self) ? relationships_desc[:self].keys : []
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



236
237
238
# File 'lib/active_fedora/relationships.rb', line 236

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

#relationship_query(relationship_name) ⇒ String

Call this method to return the query used against solr to retrieve any objects linked via the relationship name given.

Instead of this method you can also use the helper method [relationship_name]_query, i.e. method “parts_query” for relationship “parts” to return the same value

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.parents_append(obj)
s.series_parents_query 
#=> "(id:changeme\\:13020 AND level_t:series)" 
SampleAFObjRelationshipFilterQuery.relationship_query("series_parents")
#=> "(id:changeme\\:13020 AND level_t:series)" 

Parameters:

  • The (String)

    name of the relationship defined in the model

Returns:

  • (String)

    The query used when querying solr for objects for this relationship



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/active_fedora/relationships.rb', line 70

def relationship_query(relationship_name)
  query = ""
  if self.class.is_bidirectional_relationship?(relationship_name)
    predicate = outbound_relationship_predicates["#{relationship_name}_outbound"]
    id_array = ids_for_outbound(predicate)
    query = self.class.bidirectional_relationship_query(pid,relationship_name,id_array)
  elsif outbound_relationship_names.include?(relationship_name)
    predicate = outbound_relationship_predicates[relationship_name]
    id_array = ids_for_outbound(predicate)
    query = self.class.outbound_relationship_query(relationship_name,id_array)
  elsif inbound_relationship_names.include?(relationship_name)
    query = self.class.inbound_relationship_query(pid,relationship_name)
  end
  query
end

#relationships_by_name(outbound_only = true) ⇒ Hash

Gets the relationships hash with subject mapped to relationship names instead of relationship predicates (unlike the “relationships” method in SemanticNode) It has an optional parameter of outbound_only that defaults true. If false it will include inbound relationships in the results. Also, it will only reload outbound relationships if the relationships hash has changed since the last time this method was called.

Parameters:

  • if (Boolean)

    false it will include inbound relationships (defaults to true)

Returns:

  • (Hash)

    Returns a hash of subject name (:self or :inbound) mapped to nested hashs of each relationship name mapped to an Array of objects linked via the relationship



95
96
97
98
99
100
# File 'lib/active_fedora/relationships.rb', line 95

def relationships_by_name(outbound_only=true)
  Deprecation.silence(ActiveFedora::Relationships) do
    @relationships_by_name = relationships_by_name_from_class()
  end
  outbound_only ? @relationships_by_name : @relationships_by_name.merge(:inbound=>inbound_relationships_by_name)      
end

#relationships_by_name_from_classHash

Gets relationships by name from the class using the current relationships hash and relationship name,predicate pairs.

Returns:

  • (Hash)

    returns the outbound relationships with :self mapped to nested hashs of each relationship name mapped to an Array of objects linked via the relationship



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/active_fedora/relationships.rb', line 105

def relationships_by_name_from_class()
  rels = {}
  relationship_predicates.each_pair do |subj, names|
    case subj
    when :self
      rels[:self] = {}
      names.each_pair do |name, predicate|
        set = []
        res = relationships.query(:predicate => Predicates.find_graph_predicate(predicate))
        res.each_object do |o|
          set << o.to_s
        end
        rels[:self][name] = set
      end
    when :inbound
      #nop
    end
  end
  return rels
end

#remove_relationship_by_name(name, object) ⇒ Boolean

Remove an object for the given relationship name

Parameters:

Returns:

  • (Boolean)

    return true if remove operation successful



266
267
268
269
270
271
272
# File 'lib/active_fedora/relationships.rb', line 266

def remove_relationship_by_name(name, object)
  if is_relationship_name?(name,true)
    remove_relationship(outbound_relationship_predicates[name],object)
  else
    return false
  end
end