\field_attach_update
function
Save field data for an existing entity.

Save field data for an existing entity.

When calling this function outside an entity save operation be sure to clear caches for the entity:

entity_get_controller($entity_type)
  ->resetCache(array(
  $entity_id,
));

Comments

manimejia’s picture

This documentation generating tool does not catch when functions are called from a $function_name() variable. Such is the case with node_save(), when it calls either field_attach_insert() or field_attach_update().

shrimphead’s picture

A great post about how to use this in updating a field but not the node...

http://blog.urbaninsight.com/2011/10/24/saving-nodes-fields-without-savi...
by Ki Kim

pabloroberto27’s picture

schlicki’s picture

Hey!

I have a module that sometimes loads and saves many nodes in one step. This can really get ugly when a user has to wait 10seconds to continue. It looks like the more fields the nodes have, the longer it takes to process them (sounds logical to me ;)).

Basically I do the followong:
- node_load
- change field value
- node_save

Would field_attach_update solve performance issues?

Thanks,
j

schlicki’s picture

I forget to mention that I would use the method of saving single fields only as posted by shrimphead ;)

gaborpeter’s picture

For me this setup worked:

$node = new stdClass();
$node->nid = $val;
$node->type = 'NODETYPE;
$node-field_whatever[LANGUAGE_NONE][0]['value'] = 'VALUE';
field_attach_presave('node', $node);
field_attach_update('node', $node);

AlxVallejo’s picture

I'm wondering if this is the performant way to update a node's fields. You're not using node_load so you're not creating an entire noad object from memory. Any insight?

ashishdalvi’s picture

Correcting Minor typo in above exam.

$node = new stdClass();
$node->nid = $val;
$node->type = 'NODETYPE;
$node->field_whatever[LANGUAGE_NONE][0]['value'] = 'VALUE';
field_attach_presave('node', $node);
field_attach_update('node', $node);

efpapado’s picture

I think that

field_attach_presave('node', $node);
field_attach_update('node', $node);
entity_get_controller('node')->resetCache(array($node->nid));

should be avoided when the field you're trying to save is of type "taxonomy term reference" (as it is saved on field_config_instance.type table)

That's because, when you have a classic term reference field, every time you add a value, it is being saved in 2 tables: One is the (presumably) field_data_field_FIELDNAME, and the other is the taxonomy_index table.

It seems that using this function, only the first table gets updated. So, during full node view, you can see your new term value appearing in the field, but when you view the node into the /taxonomy/term/tid listing, the node doesn't show up.

I noticed it while working on a custom module. Then I discarder field_attach_update(), and I used node_save() which seems to work perfectly.

Could anyone test and confirm this?

Chaulky’s picture

I tried this approach and got the same results. This is because the taxonomy_index table in maintained in taxonomy_node_insert() and taxonomy_node_update(). Looks like this approach won't work for taxonomy references.

arpas’s picture

I analysed drupal core code and finished with

$node = node_load($id_value);
$node->field_field_name[LANGUAGE_NONE][0]['tid'] = 76;
field_attach_presave('node', $node);
field_attach_update('node', $node);
entity_get_controller('node')->resetCache(array($id_value));
taxonomy_node_update($node);

so taxonomy_index table was updated

kikecastillo’s picture

I think a call to db_transaction function before using this function is highly recommended or it is possible to have consistency problems or even content loss.
Read more information here: https://www.drupal.org/node/355875

polaki_viswanath’s picture

Hello,
I want to insert new field collection value to a node but without updating the associated node. Is there a way to do so, Since while saving any field collection value to a node the node itself is updated.

I have found this link (http://alexrayu.com/blog/saveupdate-field-collection-without-nodesave) but its not working in case of adding new field collection values to the node.

Any help would be much appreciated.

kikecastillo’s picture

Hello,

To update a field without updating the associated node you can do it this way:

$transaction = db_transaction();
try {
$node = node_load(1); // where 1 is the nid you want to change
$update_node = new stdClass();
$update_node->nid = $node->nid;
$update_node->vid = $node->vid;
$update_node->type = $node->type;
$update_node->field_FIELD_NAME['und'][0]['value'] = VALUE_YOU_WANT_TO_CHANGE;
field_attach_update('node', $update_node);
} catch (Exception $e) {
$transaction->rollback();
throw $e;
}

If you don't use db_transaction, you can lose content.

Best regards

scotself’s picture

Through trial and error, it seems the way to do this with users , you need uid and email or for some reason the user.token.inc file throws annoying notices in watchdog:

    $user = new StdClass();
    $user->uid = $uid;
    $user->mail = $mail;
    $user->my_custom_field[LANGUAGE_NONE][0]['value'] = $new_value;
    field_attach_update('user', $user);
tame4tex’s picture

One thing to be aware of when using field_attach_update() to update field values without saving the node, is that unless you specifically set $node->changed it will not get updated. $node-changed is used by node form to determine if current data is stale.

This means that if a user opens an edit node form prior to your field_attach_update() related function being called and then saves that node form after your field_attach_update() related function has run, if they both affected the same nid, any changes you make via field_attach_update() will be overwritten by stale data from the node form.