Class: Glossarist::V3::RelationLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/glossarist/v3/relation_loader.rb

Overview

RelationLoader — scans a directory for per-file hyperedge files and returns typed instances.

Files live at relations/<comprehensive-id>/<criterion-slug>.yaml. The type field on each file discriminates which concrete hyperedge class to instantiate. Dispatch is via HyperedgeRegistry — adding a new hyperedge type requires no edit here.

Usage:

relations = RelationLoader.load_all("path/to/dataset/relations")
partitive = RelationLoader.load_for_concept("path/to/dataset", "5-1")

Defined Under Namespace

Classes: LoadError

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(relations_dir) ⇒ RelationLoader

Returns a new instance of RelationLoader.



43
44
45
# File 'lib/glossarist/v3/relation_loader.rb', line 43

def initialize(relations_dir)
  @relations_dir = Pathname.new(relations_dir)
end

Class Method Details

.load_all(dir) ⇒ Object

Load every relation file under dir. Returns a hash keyed by comprehensive id, value = array of typed hyperedges.



26
27
28
# File 'lib/glossarist/v3/relation_loader.rb', line 26

def load_all(dir)
  new(dir).load_all
end

.load_file(path) ⇒ Object

Load a single relation file. Returns a typed hyperedge instance (PartitiveHyperedge, GenericHyperedge, etc.).



38
39
40
# File 'lib/glossarist/v3/relation_loader.rb', line 38

def load_file(path)
  new(File.dirname(path, 2)).load_path(path)
end

.load_for_concept(dataset_root, comprehensive_id) ⇒ Object

Load all relation files for a single comprehensive id. dataset_root is the path containing the relations/ directory.



32
33
34
# File 'lib/glossarist/v3/relation_loader.rb', line 32

def load_for_concept(dataset_root, comprehensive_id)
  new(File.join(dataset_root, "relations")).load_for_comprehensive(comprehensive_id)
end

Instance Method Details

#load_allObject



47
48
49
50
51
52
53
# File 'lib/glossarist/v3/relation_loader.rb', line 47

def load_all
  each_relation_path.with_object({}) do |path, h|
    rel = load_path(path)
    comp_id = Glossarist::ConceptRef.qualified_id(rel.comprehensive)
    (h[comp_id] ||= []) << rel
  end
end

#load_for_comprehensive(comprehensive_id) ⇒ Object



55
56
57
58
59
60
# File 'lib/glossarist/v3/relation_loader.rb', line 55

def load_for_comprehensive(comprehensive_id)
  dir = @relations_dir.join(comprehensive_id.to_s)
  return [] unless dir.exist?

  Dir.glob("#{dir}/*.yaml").map { |p| load_path(Pathname.new(p)) }
end

#load_path(path) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/glossarist/v3/relation_loader.rb', line 62

def load_path(path)
  path = Pathname.new(path)
  doc = YAML.load_file(path)
  unless doc.is_a?(Hash) && doc["type"]
    raise LoadError, "#{path} missing required `type` field"
  end

  klass = HyperedgeRegistry.for_type_tag(doc["type"])
  unless klass
    known = HyperedgeRegistry.all_classes.map { |c| c::TYPE_TAG }.join(", ")
    raise LoadError, "#{path} has unknown type #{doc['type'].inspect}; " \
                     "expected one of #{known}"
  end

  # Preserve the source $id so round-trip writes go to the same
  # file path. Without this, write-back would derive a new path
  # from comprehensive + criterion and could fragment files.
  file_id = doc["$id"]
  instance = klass.from_hash(doc)
  instance.file_id = file_id if file_id && instance.respond_to?(:file_id=)
  instance
end