Enabling entity module when existing entity reference field depends on it

Over time you will extend functionality. Locally things work but then you need to start planning how to update existing environments and then interesting problems will arise.

One thing that could be a problem is an entity reference dependency issue. It will manifest itself with a message like "Field field_name on entity type entity_type references a target entity type entity_type which does not exist".

It can happen if you are creating a new custom entity and adding a definition to a new module. Then you are trying to reference these on existing entities with the entity reference field. Locally most likely things look fine and working as you are adding functionality incrementally. When reaching a point where you need to move to QA or some other environment, you see that an update hook is needed to enable that module. Seems simple enough - not at all, you most likely will be welcomed with that message mentioned before. 

How to fix this? I think there is no good information about it and it might depend on the projects as well. For example in my case, there is no configuration sync that deals with enabling modules and maybe it works there, I'm not sure, but with update hooks, it failed as Drupal expects to have a valid target entity type already there. It didn't matter if the field was not installed (the base field definition was described in the code and was installed later). The following things could work if you have a similar problem:

  • install the field definition with a new module, most of the time it is the correct way to do it
  • use some hook to switch out the entity type target, like hook_entity_base_field_info_alter
  • install module manually, with Drush, but it can be a problem if there are a lot of environments (can be scripted, if possible)

I chose the alter hook to switch out the target_type with a similar entity type that already exists on the system. Because I had created a configuration entity, I switched that one with a view. It is important to use a similar entity type because the entity reference field uses that information when creating a reference and it will be a problem if the storage is int, but the id's are strings.

File: my_module.module
/** * Implements hook_entity_base_field_info_alter(). */ function my_module_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type): void { // Check if the field exists and module my_entity_module is not installed. if (isset($fields['my_entity_field']) && !\Drupal::moduleHandler()->moduleExists('my_entity_module')) { // Use view configuration entities until my_entity_module is not enabled. $fields['my_entity_field']->setSetting('target_type', 'view'); } }
Buy Me a Coffee at ko-fi.com

Add new comment