Problem/Motivation
Main issue is #3095257: Option for _none is removed once a field has a value and can cause accidental data corruption but that is being worked on by Drupal CWG now.
When you create a required single-value entity reference field, for example a term reference, then the referenced entity is deleted, the _none option disappears. When the widget is loaded up it defaults to the first option in the list, and the user can easily save the new value without noticing. Steps to reproduce below.
I believe this tracks back to OptionsSelectWidget::getEmptyLabel() which checks for !$this->hasValue. It doesn't consider whether the stored value is actually present in the available options.
The data integrity issue happens when you delete an entity that is the value for an entity reference field that is required. This MR makes it less surprising when you edit the entity whose reference field is now invalid. It puts the editor back in the position of having to choose rather than having the first available value selected (as if is had that value already).
Unfortunately solving the data integrity issue at the time the entity is deleted in core is going be super super hard. This UX improvement will help a bit by being less surprising.
from @alexpott
Steps to reproduce
Install Drupal with the standard profile
Change the Tags field to Required, Allowed number of values to 1
Change the Tags widget to Select list
Create two terms in the Tags vocabulary, "foo" and "bar"
Create an article node, set the Tags field to "foo"
Delete the "foo" term
Edit the article node, the widget now has "bar" selected
Save the article node
Proposed resolution
Update OptionsSelectWidget::formElement() for when "If the selected option is empty and the field is required, add an option to force the user to choose." And simplify the ::getEmptyLabel() to only work about when the field is required.
If single or multiple value field is the selected term is deleted fallback to _none option forcing the user to select a new option.
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
Issue fork drupal-3624799
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3624799-mr-testing-issue
compare
- 3624799-new-ticket
changes, plain diff MR !17207
Comments
Comment #3
dcam commentedI finished reviewing the MR. I wanted to make certain that the changes to the empty options maintained the correct behaviors since that experienced the biggest change after my last review. I set up combinations of single/multiple option and optional/required fields for both list and reference fields. I didn't find any issue. The empty options remained the same between main and the MR branch.
Afterward, I went through the steps to reproduce the issue again. The MR fixes the original issue as described by the steps. The widget changes to the empty option. Also upon the term deletion, the multiple-select widget changes single-select widget with the empty option as the default. This is verified by the new automated test.
Comment #4
smustgrave commentedComment #5
acbramley commentedso is this issue the place where this will get committed? because there's a new commit on the other MR https://git.drupalcode.org/project/drupal/-/merge_requests/15023/diffs?c...
Comment #6
alexpott