Class: ActiveFedora::Base

Inherits:
Object
  • Object
show all
Includes:
RelationshipsHelper, SemanticNode
Defined in:
lib/active_fedora/base.rb

Overview

This class ties together many of the lower-level modules, and implements something akin to an ActiveRecord-alike interface to fedora. If you want to represent a fedora object in the ruby space, this is the class you want to extend.

The Basics

class Oralhistory < ActiveFedora::Base
   :name => "properties", :type => ActiveFedora::MetadataDatastream do |m|
    m.field "narrator",  :string
    m.field "narrator",  :text
  end
end

The above example creates a FedoraObject with a metadata datastream named “properties”, which is composed of a narrator and bio field.

Datastreams defined with has_metadata are accessed via the datastreams member hash.

Implementation

This class is really a facade for a basic Fedora::FedoraObject, which is stored internally.

Direct Known Subclasses

ContentModel, SpecialThing

Instance Attribute Summary collapse

Attributes included from SemanticNode

#load_from_solr, #named_relationship_desc, #relationships_are_dirty

Class Method Summary collapse

Instance Method Summary collapse

Methods included from SemanticNode

#inbound_relationships, #load_inbound_relationship, #load_outbound_relationship, #outbound_relationships, #register_predicate, #register_subject, #register_triple, #relationship_exists?, #relationships_from_class, #to_rels_ext, #unregister_triple

Methods included from RelationshipsHelper

#add_named_relationship, #add_relationship_by_name, #assert_conforms_to, #assert_kind_of_model, #class_from_name, #conforms_to?, #find_relationship_by_name, #inbound_named_relationship_predicates, #inbound_relationship_names, #inbound_relationship_predicates, #inbound_relationships_by_name, #is_named_relationship?, #is_relationship_name?, #kind_of_model?, #named_inbound_relationships, #named_outbound_relationships, #named_relationship, #named_relationship_predicates, #named_relationship_predicates_from_class, #named_relationship_query, #named_relationship_type, #named_relationships, #named_relationships_desc, #named_relationships_desc_from_class, #named_relationships_from_class, #outbound_named_relationship_predicates, #outbound_relationship_names, #outbound_relationship_predicates, #outbound_relationships_by_name, #register_named_relationship, #register_named_subject, #register_relationship_desc, #register_relationship_desc_subject, #relationship_model_type, #relationship_names, #relationship_predicates, #relationship_predicates_from_class, #relationship_query, #relationships_by_name, #relationships_by_name_from_class, #relationships_desc, #relationships_desc_from_class, #remove_named_relationship, #remove_relationship_by_name

Constructor Details

#initialize(attrs = nil) ⇒ Base

Constructor. If attrs does not comtain :pid, we assume we’re making a new one, and call off to the Fedora Rest API for the next available Fedora pid, and mark as new object. Also, if attrs does not contain :pid but does contain :namespace it will pass the :namespace value to Fedora::Repository.nextid to generate the next pid available within the given namespace.

If there is a pid, we’re re-hydrating an existing object, and new object is false. Once the @inner_object is stored, we configure any defined datastreams.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/active_fedora/base.rb', line 82

def initialize(attrs = nil)
  attrs = {} if attrs.nil?
  unless attrs[:pid]
    if attrs[:namespace]
      attrs = attrs.merge!({:pid=>Fedora::Repository.instance.nextid({:namespace=>attrs[:namespace]})})
    else
      attrs = attrs.merge!({:pid=>Fedora::Repository.instance.nextid})  
    end
    @new_object=true
  else
    @new_object = attrs[:new_object] == false ? false : true
  end
  @inner_object = Fedora::FedoraObject.new(attrs)
  @datastreams = {}
  configure_defined_datastreams

  attributes = attrs.dup
  [:pid, :namespace, :new_object,:create_date, :modified_date].each { |k| attributes.delete(k)}
  self.attributes=attributes
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/active_fedora/base.rb', line 112

def method_missing(name, *args)
  if datastreams.has_key? name.to_s
    ### Create and invoke a proxy method 
    self.class.class_eval <<-end_eval
      def #{name.to_s}()
        datastreams["#{name.to_s}"]
      end
    end_eval

    self.send(name)
  else 
    super
  end
end

Instance Attribute Details

#named_datastreams_descObject

** EXPERIMENTAL **

Returns the hash that stores arguments passed to has_datastream calls within an ActiveFedora::Base child class.

has_datastream :name=>"audio_file", :prefix=>"AUDIO", :type=>ActiveFedora::Datastream, :mimeType=>"audio/x-wav" 
has_datastream :name=>"external_images", :prefix=>"EXTIMG", :type=>ActiveFedora::Datastream,:mimeType=>"image/jpeg", :controlGroup=>'E'

The above examples result in the following hash

{"audio_file"=>{:prefix=>"AUDIO",:type=>ActiveFedora::Datastream, :mimeType=>"audio/x-wav", :controlGroup=>'M'},
 "external_images=>{:prefix=>"EXTIMG", :type=>ActiveFedora::Datastream,:mimeType=>"image/jpeg", :controlGroup=>'E'}}

This hash is later used when adding a named datastream such as an “audio_file” as defined above.



597
598
599
# File 'lib/active_fedora/base.rb', line 597

def named_datastreams_desc
  @named_datastreams_desc
end

Class Method Details

.create_named_datastream_finders(name, prefix) ⇒ Object

** EXPERIMENTAL **

Creates the following helper methods for a datastream name

[datastream_name]  - Returns array of named datastreams
[datastream_name]_ids - Returns array of named datastream dsids

Examples for “thumbnails” datastream

thumbnails        -  Get array of thumbnail datastreams
thumbnails_ids    -  Get array of dsid's for thumbnail datastreams


698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
# File 'lib/active_fedora/base.rb', line 698

def self.create_named_datastream_finders(name, prefix)
  class_eval <<-END
  def #{name}(opts={})
    id_array = []
    keys = datastreams.keys
    id_array = keys.select {|v| v =~ /#{prefix}\d*/}
    if opts[:response_format] == :id_array
      return id_array
    else
      named_ds = []
      id_array.each do |name|
        if datastreams.has_key?(name)
          named_ds.push(datastreams[name])
        end
      end
      return named_ds
    end
  end
  def #{name}_ids
    #{name}(:response_format => :id_array)
  end
  END
end

.create_named_datastream_update_methods(name) ⇒ Object

** EXPERIMENTAL **

Creates the following helper methods for a datastream name

[datastream_name]_append  - Add a named datastream

Examples for “thumbnails” datastream

thumbnails_append -  Append a thumbnail datastream

TODO: Add [datastream_name]_remove



671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
# File 'lib/active_fedora/base.rb', line 671

def self.create_named_datastream_update_methods(name)
  append_file_method_name = "#{name.to_s.downcase}_file_append"
  append_method_name = "#{name.to_s.downcase}_append"
  #remove_method_name = "#{name.to_s.downcase}_remove"
  self.send(:define_method,:"#{append_file_method_name}") do |*args| 
    file,opts = *args
    opts ||= {}
    add_named_file_datastream(name,file,opts)
  end
  
  self.send(:define_method,:"#{append_method_name}") do |*args| 
    opts = *args
    opts ||= {}
    #call add_named_datastream instead of add_file_named_datastream in case not managed datastream
    add_named_datastream(name,opts)
  end
end

.deserialize(doc) ⇒ Object

Create an instance of the current Model from the given FOXML This method is used when you call load_instance on a Model

Parameters:

  • doc (Nokogiri::XML::Document)

    the FOXML of the object



841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
# File 'lib/active_fedora/base.rb', line 841

def self.deserialize(doc) #:nodoc:
  if doc.instance_of?(REXML::Document)
    pid = doc.elements['/foxml:digitalObject'].attributes['PID']
  
    proto = self.new(:pid=>pid, :new_object=>false)
    proto.datastreams.each do |name,ds|
      doc.elements.each("//foxml:datastream[@ID='#{name}']") do |el|
        # datastreams remain marked as new if the foxml doesn't have an entry for that datastream
        ds.new_object = false
        proto.datastreams[name]=ds.class.from_xml(ds, el)          
      end
    end
    proto.inner_object.new_object = false
    return proto
  elsif doc.instance_of?(Nokogiri::XML::Document)
    pid = doc.xpath('/foxml:digitalObject').first["PID"]
  
    proto = self.new(:pid=>pid, :new_object=>false)
    proto.datastreams.each do |name,ds|
      doc.xpath("//foxml:datastream[@ID='#{name}']").each do |node|
        # datastreams remain marked as new if the foxml doesn't have an entry for that datastream
        ds.new_object = false
        # Nokogiri Datstreams use a new syntax for .from_xml (tmpl is optional!) and expects the actual xml content rather than the foxml datstream xml
        # NB: Base.deserialize, or a separately named method, should set any other info from the foxml if necessary though by this point it's all been grabbed elsewhere... 
        if ds.kind_of?(ActiveFedora::NokogiriDatastream) 
          xml_content = Fedora::Repository.instance.fetch_custom(pid, "datastreams/#{name}/content")
          # node = node.search('./foxml:datastreamVersion[last()]/foxml:xmlContent/*').first
          proto.datastreams[name]=ds.class.from_xml(xml_content, ds)
        else
          proto.datastreams[name]=ds.class.from_xml(ds, node)          
        end
      end
    end
    proto.inner_object.new_object = false
    return proto
  end
end

.has_datastream(args) ⇒ Object

** EXPERIMENTAL **

Allows for a datastream to be treated like any other attribute of a model class while enforcing mimeType and/or datastream type (ie. external, managed, etc.) if defined.

Examples

has_datastream :name=>"thumbnails",:prefix => "THUMB",:type=>ActiveFedora::Datastream, :mimeType=>"image/jpeg", :controlGroup=>'M'                     
has_datastream :name=>"EADs", :type=>ActiveFedora::Datastream, :mimeType=>"application/xml", :controlGroup=>'M' 
has_datastream :name=>"external_images", :type=>ActiveFedora::Datastream, :controlGroup=>'E'

Required Keys in args

:name  -  name to give this datastream (must be unique)

Optional Keys in args

:prefix - used to create the DSID plus an index ie. THUMB1, THUMB2.  If :prefix is not specified, defaults to :name value in all uppercase 
:type - defaults to ActiveFedora::Datastream if you would like content specific class to be used supply it here
:mimeType - if supplied it will ensure any datastreams added are of this type, if not supplied any mimeType is acceptabl e
:controlGroup -  possible values "X", "M", "R", or "E" (InlineXML, Managed Content, Redirect, or External Referenced) If controlGroup is 'E' or 'R' it expects a dsLocation be defined when adding the datastream.

You use the datastream attribute using helper methods created for each datastream name:

Helper Method Examples

thumbnails_append -  Append a thumbnail datastream
thumbnails        -  Get array of thumbnail datastreams
thumbnails_ids    -  Get array of dsid's for thumbnail datastreams

When loading the list of datastreams for a name from Fedora it uses the DSID prefix to find them in Fedora



641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
# File 'lib/active_fedora/base.rb', line 641

def self.has_datastream(args)
  unless args.has_key?(:name)
    return false
  end
  unless args.has_key?(:prefix)
    args.merge!({:prefix=>args[:name].to_s.upcase})
  end
  unless named_datastreams_desc.has_key?(args[:name]) 
    named_datastreams_desc[args[:name]] = {} 
  end
      
  args.merge!({:mimeType=>args[:mime_type]}) if args.has_key?(:mime_type)
  
  unless named_datastreams_desc[args[:name]].has_key?(:type) 
    #default to type ActiveFedora::Datastream
    args.merge!({:type => "ActiveFedora::Datastream"})
  end
  named_datastreams_desc[args[:name]]= args   
  create_named_datastream_finders(args[:name],args[:prefix])
  create_named_datastream_update_methods(args[:name])
end

.has_metadata(args, &block) ⇒ Object

This method is used to specify the details of a datastream. args must include :name. Note that this method doesn’t actually execute the block, but stores it at the class level, to be executed by any future instantiations.



107
108
109
110
# File 'lib/active_fedora/base.rb', line 107

def self.(args, &block)
  #@ds_specs ||= Hash.new
  ds_specs[args[:name]]= [args[:type], args.fetch(:label,""), block]
end

.load_instance_from_solr(pid, solr_doc = nil) ⇒ Object

** EXPERIMENTAL **

This method can be used instead of ActiveFedora::Model::ClassMethods.load_instance.

It works similarly except it populates an object from Solr instead of Fedora. It is most useful for objects used in read-only displays in order to speed up loading time. If only a pid is passed in it will query solr for a corresponding solr document and then use it to populate this object.

If a value is passed in for optional parameter solr_doc it will not query solr again and just use the one passed to populate the object.

It will anything stored within solr such as metadata and relationships. Non-metadata datastreams will not be loaded and if needed you should use load_instance instead.



947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
# File 'lib/active_fedora/base.rb', line 947

def self.load_instance_from_solr(pid,solr_doc=nil)
  if solr_doc.nil?
    result = find_by_solr(pid)
    raise "Object #{pid} not found in solr" if result.nil?
    solr_doc = result.hits.first
    #double check pid and id in record match
    raise "Object #{pid} not found in Solr" unless !result.nil? && !solr_doc.nil? && pid == solr_doc[SOLR_DOCUMENT_ID]
  else
   raise "Solr document record id and pid do not match" unless pid == solr_doc[SOLR_DOCUMENT_ID]
 end
 
  create_date = solr_doc[ActiveFedora::SolrService.solr_name(:system_create, :date)].nil? ? solr_doc[ActiveFedora::SolrService.solr_name(:system_create, :date).to_s] : solr_doc[ActiveFedora::SolrService.solr_name(:system_create, :date)]
  modified_date = solr_doc[ActiveFedora::SolrService.solr_name(:system_create, :date)].nil? ? solr_doc[ActiveFedora::SolrService.solr_name(:system_modified, :date).to_s] : solr_doc[ActiveFedora::SolrService.solr_name(:system_modified, :date)]
  obj = self.new({:pid=>solr_doc[SOLR_DOCUMENT_ID],:create_date=>create_date,:modified_date=>modified_date})
  obj.new_object = false
  #set by default to load any dependent relationship objects from solr as well
  obj.load_from_solr = true
  #need to call rels_ext once so it exists when iterating over datastreams
  obj.rels_ext
  obj.datastreams.each_value do |ds|
    if ds.respond_to?(:from_solr)
      ds.from_solr(solr_doc) if ds.kind_of?(ActiveFedora::MetadataDatastream) || ds.kind_of?(ActiveFedora::NokogiriDatastream) || ( ds.kind_of?(ActiveFedora::RelsExtDatastream))
    end
  end
  obj
end

.named_datastreams_descObject

** EXPERIMENTAL **

Accessor for class variable for hash that stores arguments passed to has_datastream calls within an ActiveFedora::Base child class.

has_datastream :name=>"audio_file", :prefix=>"AUDIO", :type=>ActiveFedora::Datastream, :mimeType=>"audio/x-wav" 
has_datastream :name=>"external_images", :prefix=>"EXTIMG", :type=>ActiveFedora::Datastream,:mimeType=>"image/jpeg", :controlGroup=>'E'

The above examples result in the following hash

{"audio_file"=>{:prefix=>"AUDIO",:type=>ActiveFedora::Datastream, :mimeType=>"audio/x-wav", :controlGroup=>'M'},
 "external_images=>{:prefix=>"EXTIMG", :type=>ActiveFedora::Datastream,:mimeType=>"image/jpeg", :controlGroup=>'E'}}

This hash is later used when adding a named datastream such as an “audio_file” as defined above.



735
736
737
# File 'lib/active_fedora/base.rb', line 735

def self.named_datastreams_desc
  self.class_named_datastreams_desc ||= {}
end

.pids_from_uris(uris) ⇒ Object



1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
# File 'lib/active_fedora/base.rb', line 1055

def self.pids_from_uris(uris) 
  if uris.class == String
    return uris.gsub("info:fedora/", "")
  elsif uris.class == Array
    arr = []
    uris.each do |uri|
      arr << uri.gsub("info:fedora/", "")
    end
    return arr
  end
end

Instance Method Details

#add(datastream) ⇒ Object

:nodoc:



231
232
233
234
# File 'lib/active_fedora/base.rb', line 231

def add(datastream) # :nodoc:
  warn "Warning: ActiveFedora::Base.add has been deprected.  Use add_datastream"
  add_datastream(datastream)
end

#add_datastream(datastream, opts = {}) ⇒ String

Adds datastream to the object. Saves the datastream to fedora upon adding. If datastream does not have a DSID, a unique DSID is generated :prefix option will set the prefix on auto-generated DSID

Returns:

  • (String)

    dsid of the added datastream



222
223
224
225
226
227
228
229
230
# File 'lib/active_fedora/base.rb', line 222

def add_datastream(datastream, opts={})
  datastream.pid = self.pid
  if datastream.dsid == nil || datastream.dsid.empty?
    prefix = opts.has_key?(:prefix) ? opts[:prefix] : "DS"
    datastream.dsid = generate_dsid(prefix)
  end
  datastreams[datastream.dsid] = datastream
  return datastream.dsid
end

#add_file_datastream(file, opts = {}) ⇒ Object

Add the given file as a datastream in the object

Parameters:

  • file (File)

    the file to add

  • opts (Hash) (defaults to: {})

    options: :dsid, :label, :mimeType



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/active_fedora/base.rb', line 306

def add_file_datastream(file, opts={})
  label = opts.has_key?(:label) ? opts[:label] : ""
  attrs = {:dsLabel => label, :controlGroup => 'M', :blob => file}
  if opts.has_key?(:mime_type)
    attrs.merge!({:mimeType=>opts[:mime_type]})
  elsif opts.has_key?(:mimeType)
    attrs.merge!({:mimeType=>opts[:mimeType]})
  elsif opts.has_key?(:content_type)
    attrs.merge!({:mimeType=>opts[:content_type]})
  end
  
  ds = ActiveFedora::Datastream.new(attrs)
  opts.has_key?(:dsid) ? ds.dsid=(opts[:dsid]) : nil
  add_datastream(ds)
end

#add_named_datastream(name, opts = {}) ⇒ Object

** EXPERIMENTAL **

This object is used by [datastream_name]_append helper to add a named datastream but can also be called directly.

Parameters

name: name of datastream to add
opts: hash defining datastream attributes

The following are expected keys in opts hash:

:label => Defaults to the file name
:blob or :file  => Required to point to the datastream file being added if managed content
:controlGroup => defaults to 'M' for managed, can also be 'E' external and 'R' for redirected
:content_type => required if the file does not respond to 'content_type' and should match :mimeType in has_datastream definition if defined
:dsLocation => holds uri location of datastream.  Required only if :controlGroup is type 'E' or 'R'.
:dsid or :dsId => Optional, and used to update an existing datastream with dsid supplied.  Will throw an error if dsid does not exist and does not match prefix pattern for datastream name


415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'lib/active_fedora/base.rb', line 415

def add_named_datastream(name,opts={})
  
  unless named_datastreams_desc.has_key?(name) && named_datastreams_desc[name].has_key?(:type) 
    raise "Failed to add datastream. Named datastream #{name} not defined for object #{pid}." 
  end

  if opts.has_key?(:mime_type)
    opts.merge!({:content_type=>opts[:mime_type]})
  elsif opts.has_key?(:mimeType)
    opts.merge!({:content_type=>opts[:mimeType]})
  end
  opts.merge!(named_datastreams_desc[name])
    
  label = opts.has_key?(:label) ? opts[:label] : ""

  #only do these steps for managed datastreams
  unless (opts.has_key?(:controlGroup)&&opts[:controlGroup]!="M")
    if opts.has_key?(:file)
      opts.merge!({:blob => opts[:file]}) 
      opts.delete(:file)
    end
    
    raise "You must define parameter blob for this managed datastream to load for #{pid}" unless opts.has_key?(:blob)
    
    #if no explicit label and is a file use original file name for label
    if !opts.has_key?(:label)&&opts[:blob].respond_to?(:original_filename)
      label = opts[:blob].original_filename
    end
    
    if opts[:blob].respond_to?(:content_type)&&!opts[:blob].content_type.nil? && !opts.has_key?(:content_type)
      opts.merge!({:content_type=>opts[:blob].content_type})
    end

    raise "The blob must respond to content_type or the hash must have :content_type or :mime_type property set" unless opts.has_key?(:content_type)
    
    #throw error for mimeType mismatch
    if named_datastreams_desc[name].has_key?(:mimeType) && !named_datastreams_desc[name][:mimeType].eql?(opts[:content_type])
      raise "Content type mismatch for add datastream #{name} to #{pid}.  Expected: #{named_datastreams_desc[name][:mimeType]}, Actual: #{opts[:content_type]}"
    end
  else 
    label = opts[:dsLocation] if (opts.has_key?(:dsLocation)) 
  end
  
  opts.merge!(:dsLabel => label)
  
  #make sure both dsid and dsID populated if a dsid is supplied
  opts.merge!(:dsid=>opts[:dsID]) if opts.has_key?(:dsID)
  opts.merge!(:dsID=>opts[:dsid]) if opts.has_key?(:dsid)
  
  ds = create_datastream(named_datastreams_desc[name][:type],opts)
  #Must be of type datastream
  assert_kind_of 'datastream',  ds, ActiveFedora::Datastream
  #make sure dsid is nil so that it uses the prefix for mapping purposes
  #check dsid works for the prefix if it is set
  if !ds.dsid.nil? && opts.has_key?(:prefix)
    raise "dsid supplied does not conform to pattern #{opts[:prefix]}[number]" unless ds.dsid =~ /#{opts[:prefix]}[0-9]/
  end
  
  add_datastream(ds,opts)
end

#add_named_file_datastream(name, file, opts = {}) ⇒ Object

** EXPERIMENTAL **

Calls add_named_datastream while assuming it will be managed content and sets :blob and :controlGroup values accordingly

Parameters

name: Datastream name
file: The file to add for this datastream
opts: Options hash.  See +add_named_datastream+ for expected keys and values


396
397
398
399
# File 'lib/active_fedora/base.rb', line 396

def add_named_file_datastream(name, file, opts={})
  opts.merge!({:blob=>file,:controlGroup=>'M'})
  add_named_datastream(name,opts)
end

#add_relationship(predicate, obj, literal = false) ⇒ Object

Add a Rels-Ext relationship to the Object.

Parameters:

  • predicate
  • object

    Either a string URI or an object that responds to .pid



754
755
756
757
758
759
760
761
762
# File 'lib/active_fedora/base.rb', line 754

def add_relationship(predicate, obj, literal=false)
  r = ActiveFedora::Relationship.new(:subject=>:self, :predicate=>predicate, :object=>obj, :is_literal=>literal)
  unless relationship_exists?(r.subject, r.predicate, r.object)
    rels_ext.add_relationship(r)
    #need to call here to indicate update of named_relationships
    @relationships_are_dirty = true
    rels_ext.dirty = true
  end
end

#assert_kind_of(n, o, t) ⇒ Object

** EXPERIMENTAL **

Throws an assertion failure unless the object ‘o’ is kind_of? class ‘t’

Parameters

n: Name of object
o: The object to test
t: The class type to check is kind_of?


498
499
500
# File 'lib/active_fedora/base.rb', line 498

def assert_kind_of(n, o,t)
  raise "Assertion failure: #{n}: #{o} is not of type #{t}" unless o.kind_of?(t)
end

#attributes=(properties) ⇒ Object



68
69
70
71
72
# File 'lib/active_fedora/base.rb', line 68

def attributes=(properties)
  properties.each do |k, v|
    respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
  end
end

#collection_members_append(obj) ⇒ ActiveFedora::Base

Add the given obj as a collection member to the current object using an outbound has_collection_member relationship.

Examples:

This will add a has_collection_member relationship to the parent_object’s RELS-EXT datastream pointing at child_object

parent_object.collection_members_append(child_object)

Parameters:

Returns:



373
374
375
376
# File 'lib/active_fedora/base.rb', line 373

def collection_members_append(obj)
  add_relationship(:has_collection_member, obj)
  return self
end

#collection_members_removeObject



378
379
380
# File 'lib/active_fedora/base.rb', line 378

def collection_members_remove()
  # will rely on SemanticNode.remove_relationship once it is implemented
end

#create_datastream(type, opts = {}) ⇒ Object



609
610
611
612
# File 'lib/active_fedora/base.rb', line 609

def create_datastream(type,opts={})
  type.to_s.split('::').inject(Kernel) {|scope, const_name| 
  scope.const_get(const_name)}.new(opts)
end

#create_dateObject

return the create_date of the inner object (unless it’s a new object)



815
816
817
# File 'lib/active_fedora/base.rb', line 815

def create_date
  @inner_object.create_date unless new_object?
end

#datastream_namesObject

** EXPERIMENTAL **

Returns array of datastream names defined for this object



385
386
387
# File 'lib/active_fedora/base.rb', line 385

def datastream_names
  named_datastreams_desc.keys
end

#datastreamsObject

Returns all known datastreams for the object. If the object has been saved to fedora, the persisted datastreams will be included. Datastreams that have been modified in memory are given preference over the copy in Fedora.



186
187
188
189
190
191
192
193
# File 'lib/active_fedora/base.rb', line 186

def datastreams
  if @new_object
    @datastreams = datastreams_in_memory
  else
    @datastreams = (@datastreams == {}) ? datastreams_in_fedora : datastreams_in_memory
  end

end

#datastreams_attributesObject

** EXPERIMENTAL **

For all datastream objects, this returns hash of dsid mapped to attribute hash within the corresponding datastream object.



576
577
578
579
580
581
582
# File 'lib/active_fedora/base.rb', line 576

def datastreams_attributes
  ds_values = {}
  self.datastreams.each_pair do |dsid,ds|
    ds_values.merge!({dsid=>ds.attributes})
  end
  return ds_values
end

#datastreams_in_fedoraObject

:nodoc:



195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/active_fedora/base.rb', line 195

def datastreams_in_fedora #:nodoc:
  mds = {}
  self.datastreams_xml['datastream'].each do |ds|
    ds.merge!({:pid => self.pid, :dsID => ds["dsid"], :dsLabel => ds["label"]})
    if ds["dsid"] == "RELS-EXT" 
      mds.merge!({ds["dsid"] => ActiveFedora::RelsExtDatastream.new(ds)})
    else
      mds.merge!({ds["dsid"] => ActiveFedora::Datastream.new(ds)})
    end
    mds[ds["dsid"]].new_object = false
  end
  mds
end

#datastreams_in_memoryObject

:ndoc:



209
210
211
# File 'lib/active_fedora/base.rb', line 209

def datastreams_in_memory #:ndoc:
  @datastreams ||= Hash.new
end

#datastreams_xmlObject

return the datastream xml representation direclty from Fedora



214
215
216
# File 'lib/active_fedora/base.rb', line 214

def datastreams_xml
  datastreams_xml = XmlSimple.xml_in(Fedora::Repository.instance.fetch_custom(self.pid, :datastreams))
end

#dcObject

Return the Dublin Core (DC) Datastream. You can also get at this via the datastreams.



282
283
284
285
# File 'lib/active_fedora/base.rb', line 282

def dc
  #dc = REXML::Document.new(datastreams["DC"].content)
  return  datastreams["DC"] 
end

#deleteObject

Deletes a Base object, also deletes the info indexed in Solr, and the underlying inner_object. If this object is held in any relationships (ie inbound relationships outside of this object it will remove it from those items rels-ext as well



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/active_fedora/base.rb', line 157

def delete
  inbound_relationships(:objects).each_pair do |predicate, objects|
    objects.each do |obj|
      if obj.respond_to?(:remove_relationship)
        obj.remove_relationship(predicate,self)
        obj.save
      end 
    end
  end
  
  Fedora::Repository.instance.delete(@inner_object)
  if ENABLE_SOLR_UPDATES
    ActiveFedora::SolrService.instance.conn.delete(pid) 
    # if defined?( Solrizer::Solrizer ) 
    #   solrizer = Solrizer::Solrizer.new
    #   solrizer.solrize_delete(pid)
    # end
  end
end

#errorsObject

return the error list of the inner object (unless it’s a new object)



825
826
827
# File 'lib/active_fedora/base.rb', line 825

def errors
  @inner_object.errors
end

#fieldsObject

Return a hash of all available metadata fields for all ActiveFedora::MetadataDatastream datastreams, as well as system_create_date, system_modified_date, active_fedora_model_field, and the object id.



883
884
885
886
887
888
889
# File 'lib/active_fedora/base.rb', line 883

def fields
  fields = {:id => {:values => [pid]}, :system_create_date => {:values => [self.create_date], :type=>:date}, :system_modified_date => {:values => [self.modified_date], :type=>:date}, :active_fedora_model => {:values => [self.class.inspect], :type=>:symbol}}
  datastreams.values.each do |ds|        
    fields.merge!(ds.fields) if ds.kind_of?(ActiveFedora::MetadataDatastream)
  end
  return fields
end

#file_objects(opts = {}) ⇒ Array of ActiveFedora objects, ...

List the objects that assert isPartOf pointing at this object plus all objects that this object asserts hasPart for

Note: Previous versions of ActiveFedora used hasCollectionMember to represent this type of relationship.  
To accommodate this, until active-fedora-1.3, .file_assets will also return anything that this asserts hasCollectionMember for and will output a warning in the logs.

Parameters:

  • opts (Hash) (defaults to: {})

    – same options as auto-generated methods for relationships (ie. :response_format)

Returns:

  • (Array of ActiveFedora objects, Array of PIDs, or Solr::Result)

    – same options as auto-generated methods for relationships (ie. :response_format)



328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/active_fedora/base.rb', line 328

def file_objects(opts={})
  cm_array = collection_members(:response_format=>:id_array)
  
  if !cm_array.empty?
    logger.warn "This object has collection member assertions.  hasCollectionMember will no longer be used to track file_object relationships after active_fedora 1.3.  Use isPartOf assertions in the RELS-EXT of child objects instead."
    if opts[:response_format] == :solr || opts[:response_format] == :load_from_solr
      logger.warn ":solr and :load_from_solr response formats for file_objects search only uses parts relationships (usage of hasCollectionMember is no longer supported)"
      result = parts(opts)
    else
      cm_result = collection_members(opts)
      parts_result = parts(opts)
      ary = cm_result+parts_result
      result = ary.uniq
    end
  else
    result = parts(opts)
  end
  return result
end

#file_objects_append(obj) ⇒ Boolean

Add the given obj as a child to the current object using an inbound is_part_of relationship

Examples:

This will add an is_part_of relationship to the child_object’s RELS-EXT datastream pointing at parent_object

parent_object.file_objects_append(child_object)

Parameters:

Returns:

  • (Boolean)

    whether saving the child object was successful



354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/active_fedora/base.rb', line 354

def file_objects_append(obj)
  # collection_members_append(obj)
  unless obj.kind_of? ActiveFedora::Base
    begin
      obj = ActiveFedora::Base.load_instance(obj)
    rescue ActiveFedora::ObjectNotFoundError
      "You must provide either an ActiveFedora object or a valid pid to add it as a file object.  You submitted #{obj.inspect}"
    end
  end
  obj.add_relationship(:is_part_of, self)
  obj.save
end

#file_streamsObject

return all datastreams not of type ActiveFedora::MetadataDatastream (that aren’t Dublin Core or RELS-EXT streams either)



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

def file_streams
  results = []
  datastreams.each_value do |ds|
    if !ds.kind_of?(ActiveFedora::MetadataDatastream) 
      dsid = ds.dsid
      if dsid != "DC" && dsid != "RELS-EXT"
        results<<ds
      end
    end
  end
  return results
end

#generate_dsid(prefix = "DS") ⇒ Object

return a valid dsid that is not currently in use. Uses a prefix (default “DS”) and an auto-incrementing integer Example: if there are already datastreams with IDs DS1 and DS2, this method will return DS3. If you specify FOO as the prefix, it will return FOO1.



264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/active_fedora/base.rb', line 264

def generate_dsid(prefix="DS")
  keys = datastreams.keys
  next_index = keys.select {|v| v =~ /(#{prefix}\d*$)/}.length + 1
  new_dsid = prefix.to_s + next_index.to_s
  while keys.include?(new_dsid)
    next_index += 1
    new_dsid = prefix.to_s + next_index.to_s
  end
  new_dsid

  # while keys.include?(new_dsid)
  #         next_index += 1
  #         new_dsid = prefix.to_s + rand(range).to_s
  #       end
end

#get_values_from_datastream(dsid, field_key, default = []) ⇒ Object



1047
1048
1049
1050
1051
1052
1053
# File 'lib/active_fedora/base.rb', line 1047

def get_values_from_datastream(dsid,field_key,default=[])
  if datastreams_in_memory.include?(dsid)
    return datastreams_in_memory[dsid].get_values(field_key,default)
  else
    return nil
  end
end

#idObject

Needed for the nested form helper



787
788
789
# File 'lib/active_fedora/base.rb', line 787

def id   ### Needed for the nested form helper
  self.pid
end

#inner_objectObject

:nodoc



777
778
779
# File 'lib/active_fedora/base.rb', line 777

def inner_object # :nodoc
  @inner_object
end

#internal_uriObject

return the internal fedora URI



796
797
798
# File 'lib/active_fedora/base.rb', line 796

def internal_uri
  "info:fedora/#{pid}"
end

#is_named_datastream?(name) ⇒ Boolean

** EXPERIMENTAL **

Returns true if the name is a defined named datastream

Returns:

  • (Boolean)


505
506
507
# File 'lib/active_fedora/base.rb', line 505

def is_named_datastream?(name)
  named_datastreams_desc.has_key?(name)
end

#labelObject

return the label of the inner object (unless it’s a new object)



830
831
832
# File 'lib/active_fedora/base.rb', line 830

def label
  @inner_object.label
end

#label=(new_label) ⇒ Object



834
835
836
# File 'lib/active_fedora/base.rb', line 834

def label=(new_label)
  @inner_object.label = new_label
end

#metadata_streamsObject

return all datastreams of type ActiveFedora::MetadataDatastream



237
238
239
240
241
242
243
244
245
# File 'lib/active_fedora/base.rb', line 237

def 
  results = []
  datastreams.each_value do |ds|
    if ds.kind_of?(ActiveFedora::MetadataDatastream) || ds.kind_of?(ActiveFedora::NokogiriDatastream)
      results<<ds
    end
  end
  return results
end

#modified_dateObject

return the modification date of the inner object (unless it’s a new object)



820
821
822
# File 'lib/active_fedora/base.rb', line 820

def modified_date
  @inner_object.modified_date unless new_object?
end

#named_datastreamsObject

** EXPERIMENTAL **

Returns hash of datastream names defined by has_datastream calls mapped to array of datastream objects that have been added

Example

For the following has_datastream entries and a datastream defined for minivan only would be

has_datastream :name=>"minivan", :prefix => "VAN", :type=>ActiveFedora::Datastream,:mimeType=>"image/jpeg", :controlGroup=>'M'
has_datastream :name=>"external_images", :prefix=>"EXTIMG", :type=>ActiveFedora::Datastream,:mimeType=>"image/jpeg", :controlGroup=>'E'

Returns

{"external_images"=>[],"thumbnails"=>{#<ActiveFedora::Datastream:0x7ffd6512daf8 @new_object=true,...}}


520
521
522
523
524
525
526
# File 'lib/active_fedora/base.rb', line 520

def named_datastreams
  ds_values = {}
  self.class.named_datastreams_desc.keys.each do |name|
    ds_values.merge!({name=>self.send("#{name}")})
  end
  return ds_values
end

#named_datastreams_attributesObject

** EXPERIMENTAL **

Returns hash of datastream names mapped to another hash of dsid to attributes for corresponding datastream objects

Example

For the following has_datastream call, assume we have added one datastream.

has_datastream :name=>"thumbnails",:prefix => "THUMB",:type=>ActiveFedora::Datastream, :mimeType=>"image/jpeg", :controlGroup=>'M'

It would then return

{"thumbnails"=>{"THUMB1"=>{:prefix=>"VAN", :type=>"ActiveFedora::Datastream", :dsid=>"THUMB1", :dsID=>"THUMB1", :pid=>"changme:33", :mimeType=>"image/jpeg", :dsLabel=>"", :name=>"thumbnails", :content_type=>"image/jpeg", :controlGroup=>"M"}}}


539
540
541
542
543
544
545
546
547
548
549
550
# File 'lib/active_fedora/base.rb', line 539

def named_datastreams_attributes
  ds_values = {}
  self.class.named_datastreams_desc.keys.each do |name|
    ds_array = self.send("#{name}")
    result_hash = {}
    ds_array.each do |ds|
      result_hash[ds.dsid]=ds.attributes
    end
    ds_values.merge!({name=>result_hash})
  end
  return ds_values
end

#named_datastreams_desc_from_classObject

** EXPERIMENTAL **

Get class variable hash that stores has_datastream arguments. It is used to initialize the value returned by public named_datastreams_desc method



605
606
607
# File 'lib/active_fedora/base.rb', line 605

def named_datastreams_desc_from_class
  self.class.named_datastreams_desc
end

#named_datastreams_idsObject

** EXPERIMENTAL **

Returns hash of datastream names mapped to an array of dsid’s for named datastream objects

Example

For the following has_datastream call, assume we have added two datastreams.

has_datastream :name=>"thumbnails",:prefix => "THUMB",:type=>ActiveFedora::Datastream, :mimeType=>"image/jpeg", :controlGroup=>'M'

It would then return

{"thumbnails=>["THUMB1", "THUMB2"]}


563
564
565
566
567
568
569
570
# File 'lib/active_fedora/base.rb', line 563

def named_datastreams_ids
  dsids = {}
  self.class.named_datastreams_desc.keys.each do |name|
    dsid_array = self.send("#{name}_ids")
    dsids[name] = dsid_array
  end
  return dsids
end

#new_object=(bool) ⇒ Object



54
55
56
57
# File 'lib/active_fedora/base.rb', line 54

def new_object=(bool)
  @new_object = bool
  inner_object.new_object = bool
end

#new_object?Boolean

Has this object been saved?

Returns:

  • (Boolean)


50
51
52
# File 'lib/active_fedora/base.rb', line 50

def new_object?
  @new_object
end

#new_record?Boolean

Required by associations

Returns:

  • (Boolean)


60
61
62
# File 'lib/active_fedora/base.rb', line 60

def new_record?
  self.new_object?
end

#owner_idObject

return the owner id



806
807
808
# File 'lib/active_fedora/base.rb', line 806

def owner_id
  @inner_object.owner_id
end

#owner_id=(owner_id) ⇒ Object



810
811
812
# File 'lib/active_fedora/base.rb', line 810

def owner_id=(owner_id)
  @inner_object.owner_id=(owner_id)
end

#persisted?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/active_fedora/base.rb', line 64

def persisted?
  !new_object?
end

#pidObject

return the pid of the Fedora Object



782
783
784
# File 'lib/active_fedora/base.rb', line 782

def pid
  @inner_object.pid
end

#refreshObject

Refreshes the object’s info from Fedora Note: Currently just registers any new datastreams that have appeared in fedora



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

def refresh
  inner_object.load_attributes_from_fedora
  @datastreams = datastreams_in_fedora.merge(datastreams_in_memory)
end

#relationships(outbound_only = true) ⇒ Hash

Rely on rels_ext datastream to track relationships array Overrides accessor for relationships array used by SemanticNode. If outbound_only is false, inbound relationships will be included.

Returns:

  • (Hash)

    relationships hash, as defined by SemanticNode



747
748
749
# File 'lib/active_fedora/base.rb', line 747

def relationships(outbound_only=true)
  outbound_only ? rels_ext.relationships : rels_ext.relationships.merge(:inbound=>inbound_relationships)
end

#rels_extObject

Returns the RELS-EXT Datastream Tries to grab from in-memory datastreams first Failing that, attempts to load from Fedora and addst to in-memory datastreams Failing that, creates a new RelsExtDatastream and adds it to the object



291
292
293
294
295
296
# File 'lib/active_fedora/base.rb', line 291

def rels_ext
  if !datastreams.has_key?("RELS-EXT") 
    add_datastream(ActiveFedora::RelsExtDatastream.new)
  end
  return datastreams["RELS-EXT"]
end

#remove_relationship(predicate, obj, literal = false) ⇒ Object

** EXPERIMENTAL **

Remove a Rels-Ext relationship from the Object.

Parameters:

  • predicate
  • object

    Either a string URI or an object that responds to .pid



769
770
771
772
773
774
775
# File 'lib/active_fedora/base.rb', line 769

def remove_relationship(predicate, obj, literal=false)
  r = ActiveFedora::Relationship.new(:subject=>:self, :predicate=>predicate, :object=>obj, :is_literal=>literal)
  rels_ext.remove_relationship(r)
  #need to call here to indicate update of named_relationships
  @relationships_are_dirty = true
  rels_ext.dirty = true
end

#saveObject

Saves a Base object, and any dirty datastreams, then updates the Solr index for this object.



129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/active_fedora/base.rb', line 129

def save
  #@metadata_is_dirty = false
  # If it's a new object, set the conformsTo relationship for Fedora CMA
  if new_object? 
    result = create
  else
    result = update
  end
  @new_object = false
  self.update_index if @metadata_is_dirty == true && ENABLE_SOLR_UPDATES
  @metadata_is_dirty == false
  return result
end

#save!Object



143
144
145
# File 'lib/active_fedora/base.rb', line 143

def save!
  save
end

#stateObject

return the state of the inner object



801
802
803
# File 'lib/active_fedora/base.rb', line 801

def state 
  @inner_object.state
end

#to_keyObject



791
792
793
# File 'lib/active_fedora/base.rb', line 791

def to_key
  persisted? ? [pid] : nil
end

#to_solr(solr_doc = Hash.new, opts = {}) ⇒ Object

Return a Hash representation of this object where keys in the hash are appropriate Solr field names. If opts == true, the base object metadata and the RELS-EXT datastream will be omitted. This is mainly to support shelver, which calls .to_solr for each model an object subscribes to.

Parameters:

  • solr_doc (Hash) (defaults to: Hash.new)

    (optional) Hash to insert the fields into

  • opts (Hash) (defaults to: {})

    (optional)



917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
# File 'lib/active_fedora/base.rb', line 917

def to_solr(solr_doc = Hash.new, opts={})
  unless opts[:model_only]
    solr_doc.merge!(SOLR_DOCUMENT_ID.to_sym => pid, ActiveFedora::SolrService.solr_name(:system_create, :date) => self.create_date, ActiveFedora::SolrService.solr_name(:system_modified, :date) => self.modified_date, ActiveFedora::SolrService.solr_name(:active_fedora_model, :symbol) => self.class.inspect)
  end
  datastreams.each_value do |ds|
    # solr_doc = ds.to_solr(solr_doc) if ds.class.included_modules.include?(ActiveFedora::MetadataDatastreamHelper) ||( ds.kind_of?(ActiveFedora::RelsExtDatastream) || ( ds.kind_of?(ActiveFedora::QualifiedDublinCoreDatastream) && !opts[:model_only] )
    solr_doc = ds.to_solr(solr_doc) if ds.kind_of?(ActiveFedora::MetadataDatastream) || ds.kind_of?(ActiveFedora::NokogiriDatastream) || ( ds.kind_of?(ActiveFedora::RelsExtDatastream) && !opts[:model_only] )
  end
  begin
    #logger.info("PID: '#{pid}' solr_doc put into solr: #{solr_doc.inspect}")
  rescue
    logger.info("Error encountered trying to output solr_doc details for pid: #{pid}")
  end
  return solr_doc
end

#to_xml(xml = Nokogiri::XML::Document.parse("<xml><fields/><content/></xml>")) ⇒ Object

Returns the xml version of this object as a string.



892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
# File 'lib/active_fedora/base.rb', line 892

def to_xml(xml=Nokogiri::XML::Document.parse("<xml><fields/><content/></xml>"))
  fields_xml = xml.xpath('//fields').first
  builder = Nokogiri::XML::Builder.with(fields_xml) do |fields_xml|
    fields_xml.id_ pid
    fields_xml.system_create_date self.create_date
    fields_xml.system_modified_date self.modified_date
    fields_xml.active_fedora_model self.class.inspect
  end
  
  # {:id => pid, :system_create_date => self.create_date, :system_modified_date => self.modified_date, :active_fedora_model => self.class.inspect}.each_pair do |attribute_name, value|
  #   el = REXML::Element.new(attribute_name.to_s)
  #   el.text = value
  #   fields_xml << el
  # end
  
  datastreams.each_value do |ds|  
    ds.to_xml(fields_xml) if ds.class.included_modules.include?(ActiveFedora::MetadataDatastreamHelper) || ds.kind_of?(ActiveFedora::RelsExtDatastream)
  end
  return xml.to_s
end

#update_attributes(properties) ⇒ Object



987
988
989
990
# File 'lib/active_fedora/base.rb', line 987

def update_attributes(properties)
  self.attributes=properties
  save
end

#update_datastream_attributes(params = {}, opts = {}) ⇒ Object

Updates the attributes for each datastream named in the params Hash

Examples:

Update the descMetadata and properties datastreams with new values

article = HydrangeaArticle.new
ds_values_hash = {
  "descMetadata"=>{ [{:person=>0}, :role]=>{"0"=>"role1", "1"=>"role2", "2"=>"role3"} },
  "properties"=>{ "notes"=>"foo" }
}
article.update_datastream_attributes( ds_values_hash )

Parameters:

  • params (Hash) (defaults to: {})

    A Hash whose keys correspond to datastream ids and whose values are appropriate Hashes to submit to update_indexed_attributes on that datastream

  • opts (Hash) (defaults to: {})

    (currently ignored.)



1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
# File 'lib/active_fedora/base.rb', line 1035

def update_datastream_attributes(params={}, opts={})
  result = params.dup
  params.each_pair do |dsid, ds_params| 
    if datastreams_in_memory.include?(dsid)
      result[dsid] = datastreams_in_memory[dsid].update_indexed_attributes(ds_params)
    else
      result.delete(dsid)
    end
  end
  return result
end

#update_indexObject

Updates Solr index with self.



975
976
977
978
979
980
981
982
983
984
# File 'lib/active_fedora/base.rb', line 975

def update_index
  if defined?( Solrizer::Fedora::Solrizer ) 
    #logger.info("Trying to solrize pid: #{pid}")
    solrizer = Solrizer::Fedora::Solrizer.new
    solrizer.solrize( self )
  else
    #logger.info("Trying to update solr for pid: #{pid}")
    SolrService.instance.conn.update(self.to_solr)
  end
end

#update_indexed_attributes(params = {}, opts = {}) ⇒ Object

A convenience method for updating indexed attributes. The passed in hash must look like this :

{{:name=>{"0"=>"a","1"=>"b"}}

This will result in any datastream field of name :name having the value [a,b]

An index of -1 will insert a new value. any existing value at the relevant index will be overwritten.

As in update_attributes, this overwrites all available fields by default.

If you want to specify which datastream(s) to update, use the :datastreams argument like so:

m.update_attributes({"fubar"=>{"-1"=>"mork", "0"=>"york", "1"=>"mangle"}}, :datastreams=>"my_ds")

or

m.update_attributes({"fubar"=>{"-1"=>"mork", "0"=>"york", "1"=>"mangle"}}, :datastreams=>["my_ds", "my_other_ds"])


1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
# File 'lib/active_fedora/base.rb', line 1009

def update_indexed_attributes(params={}, opts={})
  if opts[:datastreams]
    ds_array = []
    opts[:datastreams].each do |dsname|
      ds_array << datastreams[dsname]
    end
  else
    ds_array = 
  end
  result = {}
  ds_array.each do |d|
    result[d.dsid] = d.update_indexed_attributes(params,opts)
  end
  return result
end

#update_named_datastream(name, opts = {}) ⇒ Object

** EXPERIMENTAL **

Update an existing named datastream. It has same parameters as add_named_datastream except the :dsid key is now required.

TODO

Currently requires you to update file if a managed datastream but could change to allow metadata only updates as well



484
485
486
487
488
489
# File 'lib/active_fedora/base.rb', line 484

def update_named_datastream(name, opts={})
  #check that dsid provided matches existing datastream with that name
  raise "You must define parameter dsid for datastream to update for #{pid}" unless opts.include?(:dsid)
  raise "Datastream with name #{name} and dsid #{opts[:dsid]} does not exist for #{pid}" unless self.send("#{name}_ids").include?(opts[:dsid])
  add_named_datastream(name,opts)
end