Class: Bulkrax::CreateRelationshipsJob

Inherits:
ApplicationJob
  • Object
show all
Includes:
DynamicRecordLookup, Hyrax::Lockable
Defined in:
app/jobs/bulkrax/create_relationships_job.rb

Overview

Responsible for creating parent-child relationships between Works and Collections.

Handles three kinds of relationships:

  • Work to Collection

  • Collection to Collection

  • Work to Work

These can be established from either side of the relationship (i.e. from parent to child or from child to parent). This job only creates one relationship at a time. If a record needs multiple parents or children or both, individual jobs should be run for each of those relationships.

NOTE: In the context of this job, “record” is used to generically refer

to either an instance of a Work or an instance of a Collection.

NOTE: In the context of this job, “identifier” is used to generically refer

to either a record's ID or an Bulkrax::Entry's source_identifier.

Please override with your own job for custom/non-hyrax applications set Bulkrax config variable :relationship_job to your custom class

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from DynamicRecordLookup

#find_record

Instance Attribute Details

#abilityObject

Returns the value of attribute ability.



47
48
49
# File 'app/jobs/bulkrax/create_relationships_job.rb', line 47

def ability
  @ability
end

#errorsObject

Returns the value of attribute errors.



47
48
49
# File 'app/jobs/bulkrax/create_relationships_job.rb', line 47

def errors
  @errors
end

#importer_runObject

Returns the value of attribute importer_run.



47
48
49
# File 'app/jobs/bulkrax/create_relationships_job.rb', line 47

def importer_run
  @importer_run
end

#importer_run_idObject

Returns the value of attribute importer_run_id.



47
48
49
# File 'app/jobs/bulkrax/create_relationships_job.rb', line 47

def importer_run_id
  @importer_run_id
end

#number_of_failuresObject

Returns the value of attribute number_of_failures.



47
48
49
# File 'app/jobs/bulkrax/create_relationships_job.rb', line 47

def number_of_failures
  @number_of_failures
end

#number_of_successesObject

Returns the value of attribute number_of_successes.



47
48
49
# File 'app/jobs/bulkrax/create_relationships_job.rb', line 47

def number_of_successes
  @number_of_successes
end

#userObject

Returns the value of attribute user.



47
48
49
# File 'app/jobs/bulkrax/create_relationships_job.rb', line 47

def user
  @user
end

Instance Method Details

#perform(parent_identifier:, importer_run_id: nil, run_user: nil, failure_count: 0) ⇒ Object

The entry_identifier is used to lookup the @base_entry for the job (a.k.a. the entry the job was called from). The @base_entry defines the context of the relationship (e.g. “this entry (@base_entry) should have a parent”). Whether the @base_entry is the parent or the child in the relationship is determined by the presence of a parent_identifier or child_identifier param. For example, if a parent_identifier is passed, we know @base_entry is the child in the relationship, and vice versa if a child_identifier is passed.

rubocop:disable Metrics/MethodLength

Parameters:

  • parent_identifier (String)

    Work/Collection ID or Bulkrax::Entry source_identifiers

  • importer_run (Bulkrax::ImporterRun)

    current importer run (needed to properly update counters)



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'app/jobs/bulkrax/create_relationships_job.rb', line 59

def perform(parent_identifier:, importer_run_id: nil, run_user: nil, failure_count: 0) # rubocop:disable Metrics/AbcSize
  @importer_run_id = importer_run_id
  @importer_run = Bulkrax::ImporterRun.find(@importer_run_id) if @importer_run_id
  @user = run_user || importer_run&.user
  @ability = Ability.new(@user)

  @number_of_successes = 0
  @number_of_failures = 0
  @errors = []
  @parent_record_members_added = false

  parent_entry, parent_record = find_record(parent_identifier, @importer_run_id)
  if parent_record
    # Works and collections are different breeds of animals:
    # - works know both their children (file_sets and child works) in member_ids
    # - works and collections know their parents (collections) in member_of_collection_ids
    # We need to handle the two differently by locking the records appropriately to avoid race condition errors.
    if parent_record.is_a?(Bulkrax.collection_model_class)
      process_parent_as_collection(parent_record: parent_record, parent_identifier: parent_identifier)
    else
      process_parent_as_work(parent_record: parent_record, parent_identifier: parent_identifier)
    end
  else
    @number_of_failures = 1
    @errors = ["Parent record #{parent_identifier} not yet available for creating relationships with children records."]
  end

  if @errors.present?
    # rubocop:disable Rails/SkipsModelValidations
    ImporterRun.update_counters(@importer_run_id, failed_relationships: @number_of_failures)
    # rubocop:enable Rails/SkipsModelValidations

    parent_entry&.set_status_info(@errors.last, importer_run)
    failure_count += 1

    if failure_count < max_failure_count
      reschedule(
        parent_identifier: parent_identifier,
        importer_run_id: @importer_run_id,
        run_user: @user,
        failure_count: failure_count
      )
    end
    return @errors # stop current job from continuing to run after rescheduling
  else
    # rubocop:disable Rails/SkipsModelValidations
    ImporterRun.update_counters(@importer_run_id, processed_relationships: @number_of_successes)
    # rubocop:enable Rails/SkipsModelValidations
  end
end

#update_child_records_works_file_setsObject

Note:

As of v5.0.1 the default behavior is to not perform this. That preserves past implementations. However, we might determine that we want to change the default behavior. Which would likely mean a major version change.

Once we’ve created the relationships, should we then index the works’s file_sets to ensure that we have the proper indexed values. This can help set things like ‘is_page_of_ssim` for IIIF manifest and search results of file sets.

Examples:

# In config/initializers/bulkrax.rb
Bulkrax::CreateRelationshipsJob.update_child_records_works_file_sets = true

See Also:

Since:

  • v5.0.1



40
# File 'app/jobs/bulkrax/create_relationships_job.rb', line 40

class_attribute :update_child_records_works_file_sets, default: false