<h2>Update 2021-09-24</h2>
<p>The actual issue is that entries fields can't hold references to <em>drafts</em> only, only to 'real' entries. Drafts have their own ID, but they aren't real entries. The entries field validates this, so any ID that doesn't belong to a real entry is silently discarded.</p>
<p>If the draft belongs to an entry that is already live, the solution is to add the ID of the live entry to the entries field. If it doesn't, saving the draft in the entries field is impossible.</p>
<hr />
<h2>Old answer</h2>
<p><strong>Edit:</strong> See comment. <strike>The most likely cause is that the field value is only updated if the entry being saved is a draft or revision – usually, you want the reverse. Maybe you're just missing a <code>!</code> there?</strike></p>
<p>In any case, you can clean your hook up a bit in order to reduce the surface area for bugs. In particular, you can attach the hook to <code>craft\elements\Entry</code> instead of <code>craft\services\Elements</code>, then you can get rid of the <code>instanceof</code> check.</p>
<p>Here's a simplified version of your hook that only applies to drafts and revisions:</p>
<pre class="lang-php prettyprint-override"><code>use Craft;
use craft\elements\Entry;
use craft\events\ModelEvent;
use craft\helpers\ElementHelper;
use yii\base\Event;

Event::on(
    Entry::class,
    Entry::EVENT_AFTER_SAVE,
    function (ModelEvent $event) {
        $entry = $event-&gt;sender;

        if (!ElementHelper::isDraftOrRevision($entry)) return;

        $user = Craft::$app-&gt;getUser()-&gt;getIdentity();
        $user-&gt;setFieldValue('myEntriesField', [$entry-&gt;id]);
        $success = Craft::$app-&gt;elements-&gt;saveElement($user);
        if (!$success) {
            $errors = $user-&gt;getErrors();
            // display or log errors
        }
    }
);
</code></pre>

CC BY-SA 4.0
2021-09-17T15:14:19.333Z
I would like to update field only if `ElementHelper::isDraftOrRevision($entry)` is true. If I check this, I get an `Getting unknown property: craft\events\ModelEvent::element` error because of `$event->element->id`. I can convert it to `$entry->id` instead, but the field remains not updated.
Romain P.
CC BY-SA 4.0
2021-09-20T07:54:18.560Z
@RomainPoirier My bad, I had a bit of the old code in there. I've updated the code example now and switched the logic to only apply to drafts and revisions. Is it still not working with that version? In any case, if you only want the hook to apply to *new*  entries, you'll probably need to add more conditions to handle drafts/revisions. See [this question](https://craftcms.stackexchange.com/q/38045/11705) for details.
MoritzLost
CC BY-SA 4.0
2021-09-20T07:59:51.183Z
@RomainPoirier If the field is still not updating correctly, check the return value of the `saveElement` method – it returns true on success or false on failure. If saving failed, it might be due to a validation error, try dumping or logging `$entry->getErrors()` after a failed attempt at saving to find any validation errors that prevent the `$user` element from saving.
MoritzLost
CC BY-SA 4.0
2021-09-20T08:23:05.953Z
The event is still correctly caught. I tried with your version, disabled the previous one, but still get no errors. I can even print the `$entry->id` value, but the field remains not updated after save... FYI I'm using a multi-sites version, where the Entry belongs to the primary one, and the form is used from the primary site.
Romain P.
CC BY-SA 4.0
2021-09-20T08:36:48.720Z
@RomainPoirier Hmmm ... that's curious. The `$user` doesn't have any validation errors either? Not sure why it's not working then :/
MoritzLost
CC BY-SA 4.0
2021-09-20T08:43:07.373Z
No error. I can even print `$user->myEntriesField` which returns an `craft\elements\db\EntryQuery Object`, where the `id` key is the same as `$entry->id`. But after the script end, it's never attached to the user's `myEntriesField`.
Romain P.
CC BY-SA 4.0
2021-09-24T13:32:30.690Z
I have created a Github ticket for this: https://github.com/craftcms/cms/issues/9876. Was it working for your using an Entries field?
Romain P.
CC BY-SA 4.0
2021-09-24T13:48:54.230Z
@RomainPoirier I had another look – so you're trying to assign a a DRAFT to an entries field? I think that might be the problem. Entries fields can only be related to 'real' entries, not drafts as far as I know. So your problem might just not have a solution in this case. If there was a [canonical version](https://github.com/craftcms/cms/blob/develop/src/base/Element.php#L2224-L2246) of the entry you could use that, but since you mentioned your entries are only drafts ... not sure if this will work. What problem are you trying to solve here, anyway? Maybe there's a better solution?
MoritzLost
CC BY-SA 4.0
2021-09-24T14:50:47.043Z
Good point for the draft. You're right, this is the problem. It's not as clean as expected, but I'm now able to assign it to the user on `EVENT_AFTER_SAVE` + `!ElementHelper::isDraftOrRevision($entry)` condition + check if the field is empty before to update it.
Romain P.
CC BY-SA 4.0
2021-09-24T15:14:55.563Z
@RomainPoirier Great! I've updated my answer so that anyone looking for something similar will know where to start :)
MoritzLost
CC BY-SA 4.0
2021-09-17T14:20:55.770Z
2023-11-27T15:20:29.757Z
2023-11-27T15:20:29.757Z
MoritzLost
<p>From a custom module, I'm listening to <code>EVENT_AFTER_SAVE_ELEMENT</code> events, to be sure to get the Entry ID after save:</p>
<pre><code>Event::on(
    Elements::class,
    Elements::EVENT_AFTER_SAVE_ELEMENT,
    function (Event $event) {
        if ($event-&gt;element instanceof Entry) {
            $entry = $event-&gt;element;
            if (ElementHelper::isDraftOrRevision($entry)) {
                $user = Craft::$app-&gt;getUser()-&gt;getIdentity();
                $user-&gt;setFieldValue('myEntriesField', [$event-&gt;element-&gt;id]);
                Craft::$app-&gt;elements-&gt;saveElement($user);
            }
        }
    }
);
</code></pre>
<p>Unfortunately, the Entries field value is never updated, while the event is correctly caught.</p>
<p>I also tried to move the field update to a service, but nothing change.
I also tried to directly changed the field in the database (using <code>Craft::$app-&gt;getDb()-&gt;createCommand()</code>), but the field isn't found (I can't also find it from the <code>craft_content</code> table).</p>
<p>Any idea why the user's custom field is not updated?</p>

CC BY-SA 4.0
2021-09-17T14:11:26.223Z
Have you verified that the hook is actually being called? For example, by writing something to a log or putting a `Craft::dd` call inside the hook? The hook looks ok, it might just be something silly like a missing `use` statement for the `Entry` class. Can you post the entire class including the namespace and imports?
MoritzLost
CC BY-SA 4.0
2021-09-17T14:19:30.603Z
The event is correctly caught. I can dump and exit the code, I can print the `$event->element->id` value, but the field isn't updated. And of course `yii\base\Event`, `craft\services\Elements`, `craft\elements\Entry` and `craft\helpers\ElementHelper` are set on top the the file. I get no error.
Romain P.
CC BY-SA 4.0
2021-09-17T14:41:32.980Z
I may be wrong, but you probably want your hook to fire only for live entries, right? In this case, your if-statement is missing a `!`, so the field is only updated when you save drafts or revisions. I'd also simplify the hook a bit, see my answer below.
MoritzLost
CC BY-SA 4.0
2021-09-17T15:02:23.743Z
No, I would like to catch only once after an Entry is created. In my case, I have an account section on front-end, where my user can create an Entry which is assigned to its `myEntriesField` field after being created. This field belongs to the user, not the Entry. It's an Entry field that will add the newly created Entry to the user's fields.
Romain P.
CC BY-SA 4.0
2021-09-17T15:05:22.217Z
I don't want this to be caught on next events, because for example if someone else resave this Entry later it should be not getting it saved to its `myEntriesField` field.
Romain P.
<users><field><modules><entries-field>
How to update a User's Entries custom field only once just after save?
# How to update a User's Entries custom field only once just after save?

(Asked by: username_0 on 2021-09-17)

From a custom module, I'm listening to EVENT_AFTER_SAVE_ELEMENT events, to be sure to get the Entry ID after save:
Event::on(
    Elements::class,
    Elements::EVENT_AFTER_SAVE_ELEMENT,
    function (Event $event) {
        if ($event->element instanceof Entry) {
            $entry = $event->element;
            if (ElementHelper::isDraftOrRevision($entry)) {
                $user = Craft::$app->getUser()->getIdentity();
                $user->setFieldValue('myEntriesField', [$event->element->id]);
                Craft::$app->elements->saveElement($user);
            }
        }
    }
);

Unfortunately, the Entries field value is never updated, while the event is correctly caught.
I also tried to move the field update to a service, but nothing change.
I also tried to directly changed the field in the database (using Craft::$app->getDb()->createCommand()), but the field isn't found (I can't also find it from the craft_content table).
Any idea why the user's custom field is not updated?

**Tags:** users, field, modules, entries-field
> **Comments:**
> **username_1**: Have you verified that the hook is actually being called? For example, by writing something to a log or putting a `Craft::dd` call inside the hook? The hook looks ok, it might just be something silly like a missing `use` statement for the `Entry` class. Can you post the entire class including the namespace and imports?  
> **username_0**: The event is correctly caught. I can dump and exit the code, I can print the `$event->element->id` value, but the field isn't updated. And of course `yii\base\Event`, `craft\services\Elements`, `craft\elements\Entry` and `craft\helpers\ElementHelper` are set on top the the file. I get no error.  
> **username_1**: I may be wrong, but you probably want your hook to fire only for live entries, right? In this case, your if-statement is missing a `!`, so the field is only updated when you save drafts or revisions. I'd also simplify the hook a bit, see my answer below.  
> **username_0**: No, I would like to catch only once after an Entry is created. In my case, I have an account section on front-end, where my user can create an Entry which is assigned to its `myEntriesField` field after being created. This field belongs to the user, not the Entry. It's an Entry field that will add the newly created Entry to the user's fields.  
> **username_0**: I don't want this to be caught on next events, because for example if someone else resave this Entry later it should be not getting it saved to its `myEntriesField` field.  

---

## 1 answers

### Answer by username_1 on 2021-09-17. Score: 1 | Accepted answer

Update 2021-09-24
The actual issue is that entries fields can't hold references to drafts only, only to 'real' entries. Drafts have their own ID, but they aren't real entries. The entries field validates this, so any ID that doesn't belong to a real entry is silently discarded.
If the draft belongs to an entry that is already live, the solution is to add the ID of the live entry to the entries field. If it doesn't, saving the draft in the entries field is impossible.

Old answer
Edit: See comment. The most likely cause is that the field value is only updated if the entry being saved is a draft or revision – usually, you want the reverse. Maybe you're just missing a ! there?
In any case, you can clean your hook up a bit in order to reduce the surface area for bugs. In particular, you can attach the hook to craft\elements\Entry instead of craft\services\Elements, then you can get rid of the instanceof check.
Here's a simplified version of your hook that only applies to drafts and revisions:
use Craft;
use craft\elements\Entry;
use craft\events\ModelEvent;
use craft\helpers\ElementHelper;
use yii\base\Event;

Event::on(
    Entry::class,
    Entry::EVENT_AFTER_SAVE,
    function (ModelEvent $event) {
        $entry = $event->sender;

        if (!ElementHelper::isDraftOrRevision($entry)) return;

        $user = Craft::$app->getUser()->getIdentity();
        $user->setFieldValue('myEntriesField', [$entry->id]);
        $success = Craft::$app->elements->saveElement($user);
        if (!$success) {
            $errors = $user->getErrors();
            // display or log errors
        }
    }
);

> **Comments:**
> **username_0**: I would like to update field only if `ElementHelper::isDraftOrRevision($entry)` is true. If I check this, I get an `Getting unknown property: craft\events\ModelEvent::element` error because of `$event->element->id`. I can convert it to `$entry->id` instead, but the field remains not updated.  
> **username_1**: @RomainPoirier My bad, I had a bit of the old code in there. I've updated the code example now and switched the logic to only apply to drafts and revisions. Is it still not working with that version? In any case, if you only want the hook to apply to *new*  entries, you'll probably need to add more conditions to handle drafts/revisions. See [this question](https://craftcms.stackexchange.com/q/38045/11705) for details.  
> **username_1**: @RomainPoirier If the field is still not updating correctly, check the return value of the `saveElement` method – it returns true on success or false on failure. If saving failed, it might be due to a validation error, try dumping or logging `$entry->getErrors()` after a failed attempt at saving to find any validation errors that prevent the `$user` element from saving.  
> **username_0**: The event is still correctly caught. I tried with your version, disabled the previous one, but still get no errors. I can even print the `$entry->id` value, but the field remains not updated after save... FYI I'm using a multi-sites version, where the Entry belongs to the primary one, and the form is used from the primary site.  
> **username_1**: @RomainPoirier Hmmm ... that's curious. The `$user` doesn't have any validation errors either? Not sure why it's not working then :/  
> **username_0**: No error. I can even print `$user->myEntriesField` which returns an `craft\elements\db\EntryQuery Object`, where the `id` key is the same as `$entry->id`. But after the script end, it's never attached to the user's `myEntriesField`.  
> **username_0**: I have created a Github ticket for this: https://github.com/craftcms/cms/issues/9876. Was it working for your using an Entries field?  
> **username_1**: @RomainPoirier I had another look – so you're trying to assign a a DRAFT to an entries field? I think that might be the problem. Entries fields can only be related to 'real' entries, not drafts as far as I know. So your problem might just not have a solution in this case. If there was a [canonical version](https://github.com/craftcms/cms/blob/develop/src/base/Element.php#L2224-L2246) of the entry you could use that, but since you mentioned your entries are only drafts ... not sure if this will work. What problem are you trying to solve here, anyway? Maybe there's a better solution?  
> **username_0**: Good point for the draft. You're right, this is the problem. It's not as clean as expected, but I'm now able to assign it to the user on `EVENT_AFTER_SAVE` + `!ElementHelper::isDraftOrRevision($entry)` condition + check if the field is empty before to update it.  
> **username_1**: @RomainPoirier Great! I've updated my answer so that anyone looking for something similar will know where to start :)  

---

