3

I'm using Drupal 7 and I have a module which has working implementation of the Entity API module.

In my_module.install file there is a hook_schema() in which I defined table columns:

$schema['my_subscription'] = array(
'description' => t('The base table for subscriptions'),
    'fields' => array(
      'sid' => array(
        'description' => t('Primary key identifier for an subscription log.'),
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'email' => array(
        'description' => t('Email of a users subscription.'),
        'type' => 'varchar',
        'length' => '250',
        'not null' => TRUE,
      ),
      'name' => array(
        'description' => t('Full name of a user subscribing.'),
        'type' => 'varchar',
        'length' => '250',
        'not null' => FALSE,
      ),
    ),
    'primary key' => array('sid'),
);

return $schema;

In my_module.module there is a hook_entity_info():

 /**
 * Implements hook_entity_info().
 */
function my_module_entity_info() {
  return array(
    'my_subscription' => array(
      'label' => t('Subscriptions'),
      'base table' => 'my_subscription',
      'entity class' => 'Entity',
      'controller class' => 'EntityAPIController',
      'fieldable' => FALSE,
      'entity keys' => array(
        'id' => 'sid',
      ),
      'bundles' => array(),
      'module' => 'my_subscription',
    ),
  );
}

Records are created from the module like this:

    $values = array(
      'email' => $email,
      'name' => $name,
    );

    $subscription = entity_create('my_subscription', $values);

It's all working good, and there are couple of hundred subscriptions at the moment.

Now I need to expand the table with one more column, I'll call it 'test' for simplicity. I added a hook_update_N() to the my_module.install, added

 db_add_field('my_subscription', 'test', array(
    'type' => 'varchar',
    'length' => 64,
    'not null' => FALSE,
  ));

and ran update.php which added the column as expected.

Now, when I try to pass new column value in the $values array like this

    $values = array(
      'email' => $email,
      'name' => $name,
      'test' => 'lorem ipsum'
    );

    $subscription = entity_create('my_subscription', $values);

record is made, but the newly added 'test' column has the value of NULL no matter what.

I suppose I need to tell Entity API that there is new field that needs to be populated as well, but I don't know how.

1 Answer 1

3

Using the API to add a column is the right thing to do, but it can't/won't update the code in your hook_schema() definition for you.

Drupal relies on that definition to map values to columns, so if you haven't explicitly declared the 'test' column, entity API doesn't know it exists, and so discards the value.

To solve, you should declare the new column in hook_schema():

$schema['my_subscription'] = array(
  'description' => t('The base table for subscriptions'),
  'fields' => array(
    'sid' => array(
      'description' => t('Primary key identifier for an subscription log.'),
      'type' => 'serial',
      'unsigned' => TRUE,
      'not null' => TRUE,
    ),
    'email' => array(
      'description' => t('Email of a users subscription.'),
      'type' => 'varchar',
      'length' => '250',
      'not null' => TRUE,
    ),
    'name' => array(
      'description' => t('Full name of a user subscribing.'),
      'type' => 'varchar',
      'length' => '250',
      'not null' => FALSE,
    ),
    'test' => array(
      'description' => t('Test field.'),
      'type' => 'varchar',
      'length' => 255,
    ),
  ),
  'primary key' => array('sid'),
);

After you clear caches things should start working.

1
  • It worked. I assumed that changing the hook_schema "ever" ... will collide with the matching db_add_field() when hook_update_N() is run. But hook_update_N() will never run for new installations. Only existing ones. New installations will use the latest hook_schema immediately.
    – user18099
    Commented Oct 1, 2016 at 15:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.