Skip to content

User mapping - Create table to enable Import User reassignment

In the improved user mapping, to support the reassignment of contributions, we need a new table that correlates the imported resource, the original user and the placeholder user / import user. In this issue, we will create the table and model and update the Direct Transfer to store the information in the table.

In the POC, a table called import_details was created to serve this purpose. The table is similar to the one described in Option 1 below. However, we will be using Option 3.

As mentioned in the POC, the table structure of this new table could be modified to increase its flexibility. Here are two options:

Proposed approaches:

Option 1
Option 1 approach
Field name Description
id
namespace_id
project_id
importable_type Polymorphic Association. Class name (Example: MergeRequest, Issue, Epic, Note)
importable_id ID of the resource
assignee_id Import::SourceUser reference
author_id Import::SourceUser reference
closed_by_id Import::SourceUser reference
created_by_id Import::SourceUser reference
last_edited_by_id Import::SourceUser reference
latest_closed_by_id Import::SourceUser reference
merge_user_id Import::SourceUser reference
merged_by_id Import::SourceUser reference
owner_id Import::SourceUser reference
resolved_by_id Import::SourceUser reference
updated_by_id Import::SourceUser reference
user_id Import::SourceUser reference

For this option, each imported resource would have a has_one association with the new table. Only the relevant foreign key would be populated.

When dealing with merge requests, four associations with the user table need to be taken into account: resolved_by_id, author_id, updated_by_id, and last_edited_by_id. For each imported merge request, a row is saved in this table, and the foreign keys resolved_by_id, author_id, updated_by_id, and last_edited_by_id are populated with the ID of an Import::SourceUser.

Option 2
Option 2 approach

Create a new table similar to the structure below and define a has_many association on all models that resources are imported.

Field name Description
id
namespace_id
project_id
importable_type Polymorphic Association. Class name (Example: MergeRequest, Issue, Epic, Note)
importable_id ID of the resource
importable_foreign_key_name Example: assignee_id, author_id, user_id
import_source_id Import::SourceUser reference

For this option, each imported resource would have a has_many association with the new table. When the imported resource references the user table multiple times, multiple rows are created.

Option 3

Create a table (or two tables) for all contributions that store the table_name, import_source_user_id and the primary keys of table_name that need to be mapped (based on a discussion in another issue: #443556 (comment 1870409887)). This approach does not use FK constraints to each imported table, so if a record gets deleted before it can be reassigned, we can skip the association when iterating over the rows in this table for a given import_source_user. The new table could look something like this:

table_name import_source_users_id primary_key* user_reference Mapped
issues_assignees 100019 {issue_id: 10, user_id: 20 } user_id FALSE
merge_requests 100019 1 'author_id' FALSE
merge_requests 100019 1 'assignee_id' FALSE
notes 100019 3 'author_id' FALSE
issues_assignees 100027 {issue_id: 10, user_id: 21 } user_id TRUE
merge_requests 100027 5 'author_id' TRUE
notes 100027 5 'assignee_id` TRUE
Field name Description
id
table_name the record's table name that will need to be reassigned as a string
import_source_users_id id of the Import::SourceUser to map records to. It may be associated to an import user instead of a placeholder user
primary_key primary key of the <table_name> record that needs to be mapped. Some primary keys will be hashes for composite primary keys*
user_reference the column on <table_name>'s record that needs to be replaced with the import_source_user placeholder id. Some tables can have multiple belongs_to user references**
Mapped boolean of whether or not this record has been reassigned yet

Notes:

* primary_key could be normalized to a separate table keep this table from getting to big, or so that we can better enforce the data types of primary_key

** user_reference is just to determine which user reference needs to be reassigned. To handle column name changes, we should have a YML file somewhere that can resolve the actual column name that needs to be updated.

Open questions

  • What should be the table name?

Selected approach

Option 3

TASKS

  • Create a new table
  • Define the model
  • Update Direct Transfer to associate imported resources with the new model in case the contribution is assigned to the Import User.
Edited by Luke Duncalfe