Module: Bulkrax::HasMatchers

Extended by:
ActiveSupport::Concern
Included in:
Entry
Defined in:
app/models/concerns/bulkrax/has_matchers.rb

Instance Method Summary collapse

Instance Method Details

#add_metadata(node_name, node_content, index = nil) ⇒ Object



30
31
32
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
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 30

def (node_name, node_content, index = nil)
  field_to(node_name).each do |name|
    matcher = self.class.matcher(name, mapping[name].symbolize_keys) if mapping[name] # the field matched to a pre parsed value in application_matcher.rb
    object_name = get_object_name(name) || false # the "key" of an object property. e.g. { object_name: { alpha: 'beta' } }
    multiple = multiple?(name) # the property has multiple values. e.g. 'letters': ['a', 'b', 'c']
    object_multiple = object_name && multiple?(object_name) # the property's value is an array of object(s)

    next unless field_supported?(name) || (object_name && field_supported?(object_name))

    if object_name
      Rails.logger.info("Bulkrax Column automatically matched object #{node_name}, #{node_content}")
      init_object_container(object_name, object_multiple)
    end

    value = if matcher
              result = matcher.result(self, node_content)
              (multiple, name, result, object_multiple)
            elsif multiple
              Rails.logger.info("Bulkrax Column automatically matched #{node_name}, #{node_content}")
              (node_content)
            else
              Rails.logger.info("Bulkrax Column automatically matched #{node_name}, #{node_content}")
              (node_content)
            end

    object_name.present? ? set_parsed_object_data(object_multiple, object_name, name, index, value) : set_parsed_data(name, value)
  end
end

#assign_object_value(target, name, value) ⇒ Object



117
118
119
120
121
122
123
124
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 117

def assign_object_value(target, name, value)
  target[name] ||= []
  if value.is_a?(Array)
    target[name] += value
  else
    target[name] = value
  end
end

#excluded?(field) ⇒ Boolean

Check whether a field is explicitly excluded in the mapping

Returns:

  • (Boolean)


234
235
236
237
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 234

def excluded?(field)
  return false if mapping[field].blank?
  mapping[field]['excluded'] || false
end

#field_supported?(field) ⇒ Boolean

Returns:

  • (Boolean)


163
164
165
166
167
168
169
170
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 163

def field_supported?(field)
  field = field.gsub('_attributes', '')

  return false if excluded?(field)
  return true if supported_bulkrax_fields.include?(field)

  Bulkrax.object_factory.field_supported?(field: field, model: factory_class, admin_set_id: importerexporter.try(:admin_set_id))
end

#field_to(field) ⇒ Array

Hyrax field to use for the given import field

Parameters:

  • field (String)

    the importer field name

Returns:

  • (Array)

    hyrax fields



218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 218

def field_to(field)
  fields = mapping&.map do |key, value|
    return unless value

    if value['from'].instance_of?(Array)
      key if value['from'].include?(field) || key == field
    elsif (value['from'] == field) || key == field
      key
    end
  end&.compact

  return [field] if fields.blank?
  return fields
end

#fields_that_are_always_multipleObject



186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 186

def fields_that_are_always_multiple
  @fields_that_are_always_multiple = %w[
    id
    delete
    model
    visibility
    visibility_during_embargo
    embargo_release_date
    visibility_after_embargo
    visibility_during_lease
    lease_expiration_date
    visibility_after_lease
  ]
end

#fields_that_are_always_singularObject



201
202
203
204
205
206
207
208
209
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 201

def fields_that_are_always_singular
  @fields_that_are_always_singular ||= %W[
    file
    remote_files
    rights_statement
    #{related_parents_parsed_mapping}
    #{related_children_parsed_mapping}
  ]
end

#get_object_name(field) ⇒ Object



59
60
61
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 59

def get_object_name(field)
  mapping&.[](field)&.[]('object')
end

#init_object_container(object_name, object_multiple) ⇒ Object



77
78
79
80
81
82
83
84
85
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 77

def init_object_container(object_name, object_multiple)
  target_key = parsed_object_target_key(object_name)
  default = if object_multiple
              nested_attributes_object?(object_name) ? {} : [{}]
            else
              {}
            end
  [target_key] ||= default
end

#matched_metadata(multiple, name, result, object_multiple) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 149

def (multiple, name, result, object_multiple)
  if object_multiple
    if mapping[name]['nested_type'] && mapping[name]['nested_type'] == 'Array'
      (result)
    else
      (result)
    end
  elsif multiple
    (result)
  else
    (result)
  end
end

#multiple?(field) ⇒ Boolean

Determine a multiple properties field

Returns:

  • (Boolean)


179
180
181
182
183
184
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 179

def multiple?(field)
  return true if fields_that_are_always_singular.include?(field.to_s)
  return false if fields_that_are_always_multiple.include?(field.to_s)

  Bulkrax.object_factory.field_multi_value?(field: field, model: factory_class, admin_set_id: importerexporter.try(:admin_set_id))
end

#multiple_metadata(content) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 132

def (content)
  return unless content

  case content
  when Nokogiri::XML::NodeSet
    content&.content
  when Array
    content
  when Hash
    Array.wrap(content)
  when String
    Array.wrap(content.strip)
  else
    Array.wrap(content)
  end
end

#nested_attributes_object?(object_name) ⇒ Boolean

When any field-mapping sibling under ‘object_name` carries `nested_attributes: true`, Bulkrax routes the imported data through `parsed_metadata` as a numbered-key hash (with `_destroy: ’false’‘ per row) — the shape consumed by Reform’s nested-attributes machinery and other ‘*_attributes`-style populators.

Returns:

  • (Boolean)


68
69
70
71
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 68

def nested_attributes_object?(object_name)
  return false unless mapping.is_a?(Hash) && object_name.present?
  mapping.any? { |_, cfg| cfg.is_a?(Hash) && cfg['object'] == object_name && cfg['nested_attributes'] }
end

#object_target_for(target_key, object_name, object_multiple, index) ⇒ Object

Resolve the hash slot that ‘name` should be written into, initializing any intermediate containers. Returns the leaf hash so the caller can assign the value with a single statement.



104
105
106
107
108
109
110
111
112
113
114
115
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 104

def object_target_for(target_key, object_name, object_multiple, index)
  return [target_key] unless object_multiple

  idx = index || 0
  if nested_attributes_object?(object_name)
    [target_key][idx.to_s] ||= { '_destroy' => 'false' }
    [target_key][idx.to_s]
  else
    [target_key][idx] ||= {}
    [target_key][idx]
  end
end

#parsed_object_target_key(object_name) ⇒ Object



73
74
75
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 73

def parsed_object_target_key(object_name)
  nested_attributes_object?(object_name) ? "#{object_name}_attributes" : object_name
end

#schema_form_definitionsObject



211
212
213
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 211

def schema_form_definitions
  @schema_form_definitions ||= ::SchemaLoader.new.form_definitions_for(factory_class.name.underscore.to_sym)
end

#set_parsed_data(name, value) ⇒ Object



87
88
89
90
91
92
93
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 87

def set_parsed_data(name, value)
  return [name] = value unless multiple?(name)

  [name] ||= []
  [name] += Array.wrap(value).flatten
  [name].uniq!
end

#set_parsed_object_data(object_multiple, object_name, name, index, value) ⇒ Object



95
96
97
98
99
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 95

def set_parsed_object_data(object_multiple, object_name, name, index, value)
  target_key = parsed_object_target_key(object_name)
  target = object_target_for(target_key, object_name, object_multiple, index)
  assign_object_value(target, name, value)
end

#single_metadata(content) ⇒ Object



126
127
128
129
130
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 126

def (content)
  content = content.content if content.is_a?(Nokogiri::XML::NodeSet)
  return unless content
  Array.wrap(content.to_s.strip).join('; ')
end

#supported_bulkrax_fieldsObject



172
173
174
175
# File 'app/models/concerns/bulkrax/has_matchers.rb', line 172

def supported_bulkrax_fields
  @supported_bulkrax_fields ||= fields_that_are_always_singular +
                                fields_that_are_always_multiple
end