The latest release of our existing module needs to define MANY new fields that are attached to the drupal user. For each field, in {module}/config/optional there is a field config and a field storage config. I then implement hook_update_n in {module}/{module}.install to detect new config entries and add them if they don't exist. Running the code installs the config (I can see it with drush cget), but does not create the corresponding DB tables for the new fields.
If I go to most pages, such as /admin/config/people/accounts/fields
, I get "The website encountered an unexpected error. Please try again later."
If I clear the caches (drush cr
), I get an error that says,
In ExceptionHandler.php line 53:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'intranet.user__field_s_uid' doesn't exist: SELECT "t".*
FROM
"user__field_s_uid" "t"
WHERE ("entity_id" IN (:db_condition_placeholder_0)) AND ("deleted" = :db_condition_placeholder_1) AND ("langcode" IN (:db_condition_placeholder_2, :db_c
ondition_placeholder_3, :db_condition_placeholder_4))
ORDER BY "delta" ASC; Array
(
[:db_condition_placeholder_0] => 0
[:db_condition_placeholder_1] => 0
[:db_condition_placeholder_2] => en
[:db_condition_placeholder_3] => und
[:db_condition_placeholder_4] => zxx
)
In StatementWrapper.php line 116:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'intranet.user__field_s_uid' doesn't exist
To get the site working again I have to delete the config (drush cdel...).
What am I missing that keeps the db storage from being created? Do I need to programatically create the db table for the field to use? (if so,how?)
file: {module}.install
<?php
use Drupal\Component\Serialization\Yaml;
use Drupal\Component\Utility\NestedArray;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\Entity\FieldConfig;
function {module}_update_9001(&$sandbox = NULL){
$modulePath = \Drupal::service('extension.list.module')
->getPath('{module}');
$config_factory = \Drupal::configFactory();
$configPathObjects = \Drupal::service('file_system')
->scanDirectory($modulePath.'/config/optional','~field.*~');
foreach ($configPathObjects as $configPath){
$config = $config_factory->getEditable($configPath->name);
if($config->isNew()){
$configSettings = NestedArray::mergeDeep(
Yaml::decode(
file_get_contents(
"$modulePath/config/optional/{$configPath->filename}"
)
),$config
);
$config->setdata($configSettings);
$config->save(TRUE);
}
}
}
file: config/optional/field.field.user.user.field_s_uid.yml
langcode: en
status: true
dependencies:
config:
- field.storage.user.field_s_uid
module:
- user
id: user.user.field_s_uid
field_name: field_s_uid
entity_type: user
bundle: user
label: s_uid
description: 'The unique ID for this user, set automatically by the DB, should not be modified by users/admins.'
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
min: null
max: null
prefix: ''
suffix: ''
field_type: integer
file: config/optional/field.storage.user.field_s_uid.yml
langcode: en
status: true
dependencies:
module:
- user
id: user.field_s_uid
field_name: field_s_uid
entity_type: user
type: integer
settings:
unsigned: false
size: normal
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false