Try to prevent cases where a tag's merger_id is non-nil but its merger is nil, and handle existing cases with fewer errors

Description

There are some tags that have a nil merger, but still have their merger_id set.

This could be caused by issues with the Tag:delete_unused rake task:

All of the unfilterable, unused tags are loaded at the beginning of the loop, but if the loop takes a while to run (which might happen if there are a lot of zero-use tags in tag sets), a tag could become canonical between the start of the loop (when the tag is loaded), and the middle of the loop (when the tag is processed). This could result in the tag being mistakenly deleted, so that any synonyms of the tag (added after the tag became canonical) would end up with a nil merger and a non-nil merger_id.

To address this, it might be necessary to do some or all of the following:

  1. Lock the tag before it's deleted, and recheck the canonical/merger_id values. This should help prevent canonical tags from being deleted, because no other transaction can set the tag to canonical while the lock is in effect, and the lock is only released once the tag is deleted.

  2. Set up the mergers association with dependent: :nullify, so that if any tags do have mergers when they're destroyed, the mergers will have their merger_id set to nil.

  3. Add a foreign key constraint to the merger_id field.

  4. Modify the tag code so that tags that are already in this state can be edited.

Testing Instructions

This is probably difficult to replicate in the wild, but it would be good to test the behavior of the tags controller on pre-existing tags with this issue:

  1. In the console, create a tag with a merger_id pointing to a deleted tag.

  2. Go to the tag edit page and make some changes.

  3. Press "Update" and make sure that you get a success message instead of an error.

Assignee

Unassigned

Reporter

ticking instant

Roadmap

Tag Wrangling

Priority

Medium

Affects versions

Fix versions

None

Components

BackEnd

Difficulty

Medium

Required Access Level

Admin

Milestone

Internal 0.9