3

I need to write a rule that edits some elements of the node, as soon as it is created. Unfortunately Drupal doesn’t like that and crashes whenever you try to save the node within a rule that was triggered by "After saving new content".

Event: After saving new content

Conditions: ...

Actions: Set a data value, with Parameter: Data: [node:field-workflow...], Value: 1

The above results in:

PDOException: SQLSTATE[23000]: Integrity constraint violation:

So far I managed to walk-around that with hook_forms, changing the workflow in my portal (so I never have to edit the node just after it is created)

Things get really interesting when I try to use "Execute custom PHP code" action which will change the node value I want:

  1. node_save will result in drupal crushing
  2. db_update - seems to work most of the time...
  3. db_insert - sometimes works (works for superuser only)

Unfortunately all my hacks don't work for all my problems. How else I can address this situation?

  • Is there a reason you can't use the "Before saving content" event? – Clive Apr 24 '13 at 15:20
  • Clive, it works!!! I always thought that if you use Before saving content, then you don't have access to the information that was just entered into forms (why else having this event). Now I know I was wrong. Thanks a lot. There are some realy creazy ways of dealing with this problem on internet but no-one ever suggested just changing to "Before saving content". – Pawel G Apr 24 '13 at 16:03
0

Have a look at issue # 430274, about an event which is a variation of your event here, and somehow explains that "after saving something" actually happens ... "before saving something" (which is not a bug, simply how the Rules module works ...).

A possible compromise to avoid these kind of issues, is to transform what you're trying to do in your Rules Action (related to Set a data value) in a Rules Component, so that your Rule "schedules the execution" (using the Rules Scheduler submodule) of that Rules Component. For example after only a few seconds or minutes later on (if your cron job runs frequent enough, otherwise it'll be next time cron runs). This compromise will ensure that, at the time the Rules Component is executed, the "Save new content" for sure completed, and your new content will have been created as expected.

PS: I'm assuming this question is about D7.

| improve this answer | |
0

In many ways, Rules is just a wrapper around core Drupal functionality. So while Rules tries to make this core functionality accessible to users who aren't hard-core Drupal programmers, there are of necessity quirks and assumptions inherited from Drupal that govern and explain how Rules behaves.

Specifically, in this case, the "After saving new content" event is just a way to access the core Drupal hook_node_insert() function. (Rules creates events for ALL the entity CRUD hooks). So if you want to understand how the "After saving new content" event works you need to understand how hook_node_insert() works. I don't know if this is explicitly described in the Rules documentation, but it's in the Drupal API documentation: https://api.drupal.org/api/drupal/modules%21node%21node.api.php/function/hook_node_insert/7.x

function hook_node_insert 7.x node.api.php hook_node_insert($node) Respond to creation of a new node. This hook is invoked from node_save() after the database query that will insert the node into the node table is scheduled for execution, after the type-specific hook_insert() is invoked, and after field_attach_insert() is called. Note that when this hook is invoked, the changes have not yet been written to the database, because a database transaction is still in progress. The transaction is not finalized until the save operation is entirely completed and node_save() goes out of scope. You should not rely on data in the database at this time as it is not updated yet. You should also note that any write/update database queries executed from this hook are also not committed immediately. Check node_save() and db_transaction() for more info.

(emphasis added)

Likewise, "Before saving content" uses the core hook_node_presave() function, where the documentation says "This hook is invoked from node_save() before the node is saved to the database." But since node_save() involves a lot of steps you need to be aware of what has been done and what hasn't been done yet at this point in the process.

The entire set of Node API Hooks is documented at https://api.drupal.org/api/drupal/modules%21node%21node.api.php/group/node_api_hooks/7.x

There's always an event that will work for what you need, it just might not be obvious which event that will be. Reading the above hook documentation should help you to figure out why the error occurred and which event would be a better fit for what you're trying to do.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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