Class: Axlsx::Relationship

Inherits:
Object
  • Object
show all
Defined in:
lib/axlsx/rels/relationship.rb

Overview

Note:

Packages automatically manage relationships.

A relationship defines a reference between package parts.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_obj, type, target, options = {}) ⇒ Relationship

Initializes a new relationship.

Parameters:

  • source_obj (Object)
  • type (String)

    The type of the relationship

  • target (String)

    The target for the relationship

  • [Symbol] (Hash)

    a customizable set of options


78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/axlsx/rels/relationship.rb', line 78

def initialize(source_obj, type, target, options={})
  @source_obj = source_obj
  self.Target=target
  self.Type=type
  self.TargetMode = options[:target_mode] if options[:target_mode]
  @Id = if (existing = self.class.instances.find{ |i| should_use_same_id_as?(i) })
    existing.Id
  else
    self.class.next_free_id
  end
  self.class.instances << self
end

Instance Attribute Details

#IdString (readonly)

The id of the relationship (eg. "rId123"). Most instances get their own unique id. However, some instances need to share the same id – see #should_use_same_id_as? for details.

Returns:

  • (String)

41
42
43
# File 'lib/axlsx/rels/relationship.rb', line 41

def Id
  @Id
end

#source_objObject (readonly)

The source object the relations belongs to (e.g. a hyperlink, drawing, ...). Needed when looking up the relationship for a specific object (see Axlsx::Relationships#for).


71
72
73
# File 'lib/axlsx/rels/relationship.rb', line 71

def source_obj
  @source_obj
end

#TargetString

The location of the relationship target

Returns:

  • (String)

45
46
47
# File 'lib/axlsx/rels/relationship.rb', line 45

def Target
  @Target
end

#TargetModeObject

The target mode of the relationship used for hyperlink type relationships to mark the relationship to an external resource TargetMode can be specified during initialization by passing in a :target_mode option Target mode must be :external for now.


67
68
69
# File 'lib/axlsx/rels/relationship.rb', line 67

def TargetMode
  @TargetMode
end

#TypeString

Note:

Supported types are defined as constants in Axlsx:

The type of relationship


61
62
63
# File 'lib/axlsx/rels/relationship.rb', line 61

def Type
  @Type
end

Class Method Details

.clear_cached_instancesObject

Clear cached instances.

This should be called before serializing a package (see Package#serialize and Package#to_stream) to make sure that serialization is idempotent (i.e. Relationship instances are generated with the same IDs everytime the package is serialized).

Also, calling this avoids memory leaks (cached instances lingering around forever).


23
24
25
# File 'lib/axlsx/rels/relationship.rb', line 23

def clear_cached_instances
  @instances = []
end

.instancesArray

Keeps track of all instances of this class.

Returns:

  • (Array)

10
11
12
# File 'lib/axlsx/rels/relationship.rb', line 10

def instances
  @instances ||= []
end

.next_free_idString

Generate and return a unique id (eg. rId123) Used for setting #Id.

The generated id depends on the number of cached instances, so using clear_cached_instances will automatically reset the generated ids, too.

Returns:

  • (String)

32
33
34
# File 'lib/axlsx/rels/relationship.rb', line 32

def next_free_id
  "rId#{@instances.size + 1}"
end

Instance Method Details

#should_use_same_id_as?(other) ⇒ Boolean

TODO:

Implement comparison of #Target based on normalized path names.

Whether this relationship should use the same id as other.

Instances designating the same relationship need to use the same id. We can not simply compare the #Target attribute, though: foo/bar.xml, ../foo/bar.xml, ../../foo/bar.xml etc. are all different but probably mean the same file (this is especially an issue for relationships in the context of pivot tables). So lets just ignore this attribute for now (except when #TargetMode is set to :External – then #Target will be an absolute URL and thus can safely be compared).

Parameters:

Returns:

  • (Boolean)

120
121
122
123
124
125
126
# File 'lib/axlsx/rels/relationship.rb', line 120

def should_use_same_id_as?(other)
  result = self.source_obj == other.source_obj && self.Type == other.Type && self.TargetMode == other.TargetMode
  if self.TargetMode == :External
    result &&= self.Target == other.Target
  end
  result
end

#to_xml_string(str = '') ⇒ String

serialize relationship

Parameters:

  • str (String) (defaults to: '')

Returns:

  • (String)

102
103
104
105
106
107
# File 'lib/axlsx/rels/relationship.rb', line 102

def to_xml_string(str = '')
  h = self.instance_values.reject{|k, _| k == "source_obj"}
  str << '<Relationship '
  str << (h.map { |key, value| '' << key.to_s << '="' << Axlsx::coder.encode(value.to_s) << '"'}.join(' '))
  str << '/>'
end