Class: Cocina::Models::Builders::NameTitleGroupBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/cocina/models/builders/name_title_group_builder.rb

Overview

Helpers for MODS nameTitleGroups.

MODS titles need to know if they match a contributor and thus need a nameTitleGroup
MODS contributors need to know if they match a title and thus need a nameTitleGroup
  If there is a match, the nameTitleGroup number has to be consistent for the matching title(s)
  and the contributor(s)

Class Method Summary collapse

Class Method Details

.build_title_values_to_contributor_name_values(title) ⇒ Hash<Hash, Hash>

When to assign nameTitleGroup to MODS from cocina:

for cocina title of type "uniform",
  look for cocina title properties :value or :structuredValue (recurse down through :parallelValue
  as needed), and look for associated :note with :type of "associated name" at the level of the
  non-empty title [value|structuredValue]
  The note of type "associated name" will have [value|structuredValue] which will match
  [value|structuredValue] for a contributor (possibly after recursing through :parallelValue).
Thus, a title [value|structuredValue] and a contributor [value|structuredValue] are associated in
cocina.

If those criteria not met in Cocina, do not assign nameTitleGroup in MODS

Returns:

  • (Hash<Hash, Hash>)

    key: hash of value or structuredValue property for title value: hash of value or structuredValue property for contributor e.g. of the artist as a young man”=>Joyce”} e.g. of the artist as a young man”=>

    [{:value=>"Joyce, James", :type=>"name",:type=>"life dates"]}}
    

    e.g. {{:structuredValue=>[{:value=>“Demanding Food”, :type=>“main”},

    Cat's Life", :type=>"subtitle"]}=>Joyce"}
    

    this complexity is needed for multilingual titles mapping to multilingual names.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/cocina/models/builders/name_title_group_builder.rb', line 33

def self.build_title_values_to_contributor_name_values(title)
  result = {}
  return result if title.blank?

  # pair title value with contributor name value
  title_value_note_slices(title).each do |value_note_slice|
    title_val_slice = slice_of_value_or_structured_value(value_note_slice)
    next if title_val_slice.blank?

    associated_name_note = value_note_slice[:note]&.detect { |note| note[:type] == 'associated name' }
    next if associated_name_note.blank?

    # relevant note will be Array of either
    #   {
    #     value: 'string contributor name',
    #     type: 'associated name'
    #   }
    # OR
    #   {
    #     structuredValue: [ structuredValue contributor name ],
    #     type: 'associated name'
    #   }
    # and we want the hash without the :type attribute
    result[title_val_slice] = slice_of_value_or_structured_value(associated_name_note)
  end
  result
end

.contributor_for_contributor_name_value_slice(contributor_name_value_slice:, contributors:) ⇒ Object



61
62
63
64
65
66
# File 'lib/cocina/models/builders/name_title_group_builder.rb', line 61

def self.contributor_for_contributor_name_value_slice(contributor_name_value_slice:, contributors:)
  Array(contributors).find do |contributor|
    contrib_name_value_slices = contributor_name_value_slices(contributor)
    contrib_name_value_slices.include?(contributor_name_value_slice)
  end
end

.contributor_name_value_slices(contributor) ⇒ Hash

Returns where we are only interested in hashes containing (either :value or :structureValue).

Returns:

  • (Hash)

    where we are only interested in hashes containing (either :value or :structureValue)



71
72
73
74
75
# File 'lib/cocina/models/builders/name_title_group_builder.rb', line 71

def self.contributor_name_value_slices(contributor)
  return if contributor&.name.blank?

  Array(contributor.name).map { |contrib_name| value_slices(contrib_name) }.flatten
end

.slice_of_value_or_structured_value(hash) ⇒ Object

for a given Hash (from a Cocina DescriptiveValue or Title or Name or …) result will be either

{ value: 'string value' }

OR

{ structuredValue: [ some structuredValue ] }


97
98
99
100
101
102
103
# File 'lib/cocina/models/builders/name_title_group_builder.rb', line 97

def self.slice_of_value_or_structured_value(hash)
  if hash[:value].present?
    hash.slice(:value).select { |_k, value| value.present? }
  elsif hash[:structuredValue].present?
    hash.slice(:structuredValue).select { |_k, value| value.present? }
  end
end

.title_value_note_slices(title) ⇒ Array<Cocina::Models::DescriptiveValue>

reduce parallelValues down to value or structuredValue for these slices

Returns:



109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/cocina/models/builders/name_title_group_builder.rb', line 109

def self.title_value_note_slices(title)
  slices = []
  title_slice = title.to_h.slice(:value, :structuredValue, :parallelValue, :note)
  if title_slice[:value].present? || title_slice[:structuredValue].present?
    slices << title_slice.select { |_k, value| value.present? }
  elsif title_slice[:parallelValue].present?
    title_slice[:parallelValue].each do |parallel_val|
      slices << title_value_note_slices(parallel_val)
    end
  end
  # ignoring groupedValue
  slices.flatten
end

.value_slices(desc_value) ⇒ Array<Cocina::Models::DescriptiveValue>

Returns where we are only interested in hashes containing (either :value or :structuredValue).

Returns:



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/cocina/models/builders/name_title_group_builder.rb', line 80

def self.value_slices(desc_value)
  slices = []
  desc_value_slice = desc_value.to_h.slice(:value, :structuredValue, :parallelValue)
  if desc_value_slice[:value].present? || desc_value_slice[:structuredValue].present?
    slices << desc_value_slice.select { |_k, value| value.present? }
  elsif desc_value_slice[:parallelValue].present?
    desc_value_slice[:parallelValue].each { |parallel_val| slices << value_slices(parallel_val) }
  end
  # ignoring groupedValue
  slices.flatten
end