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



86
87
88
89
90
91
92
# File 'lib/axlsx/rels/relationship.rb', line 86

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 = (self.class.ids_cache[ids_cache_key] ||= self.class.next_free_id)
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 #ids_cache_key for details.

Returns:

  • (String)


49
50
51
# File 'lib/axlsx/rels/relationship.rb', line 49

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).



79
80
81
# File 'lib/axlsx/rels/relationship.rb', line 79

def source_obj
  @source_obj
end

#TargetString

The location of the relationship target

Returns:

  • (String)


53
54
55
# File 'lib/axlsx/rels/relationship.rb', line 53

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.



75
76
77
# File 'lib/axlsx/rels/relationship.rb', line 75

def TargetMode
  @TargetMode
end

#TypeString

Note:

Supported types are defined as constants in Axlsx:

The type of relationship



69
70
71
# File 'lib/axlsx/rels/relationship.rb', line 69

def Type
  @Type
end

Class Method Details

.clear_ids_cacheObject

Clear cached ids.

This should be called after serializing a package (see Package#serialize and Package#to_stream) to free the memory allocated for cache.

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



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

def clear_ids_cache
  Thread.current[:axlsx_relationship_ids_cache] = nil
end

.ids_cacheArray

Keeps track of relationship ids in use.

Returns:

  • (Array)


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

def ids_cache
  Thread.current[:axlsx_relationship_ids_cache] ||= {}
end

.initialize_ids_cacheObject

Initialize cached ids.

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 every time the package is serialized).



20
21
22
# File 'lib/axlsx/rels/relationship.rb', line 20

def initialize_ids_cache
  Thread.current[:axlsx_relationship_ids_cache] = {}
end

.next_free_idString

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

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

Returns:

  • (String)


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

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

Instance Method Details

#ids_cache_keyArray

TODO:

Implement comparison of #Target based on normalized path names.

A key that determines whether this relationship should use already generated id.

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).

Returns:

  • (Array)


136
137
138
139
140
# File 'lib/axlsx/rels/relationship.rb', line 136

def ids_cache_key
  key = [source_obj, self.Type, self.TargetMode]
  key << self.Target if self.TargetMode == :External
  key
end

#to_xml_string(str = +'')) ⇒ String

serialize relationship

Parameters:

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

Returns:

  • (String)


115
116
117
118
119
120
121
122
123
# File 'lib/axlsx/rels/relationship.rb', line 115

def to_xml_string(str = +'')
  h = Axlsx.instance_values_for(self).reject { |k, _| k == "source_obj" }
  str << '<Relationship '
  h.each_with_index do |key_value, index|
    str << ' ' unless index == 0
    str << key_value.first.to_s << '="' << Axlsx.coder.encode(key_value.last.to_s) << '"'
  end
  str << '/>'
end