craftcms / craftcms/cms

Issue with`$targetIds` when saving a relation

Open
#5,711 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
PHP
Stars
3.6k
Forks
705
Avg merge
1d 5h
Merged PRs (30d)
134

Description

https://github.com/craftcms/cms/blob/c75acb570df35b4593b89e06239f59f772e937b4/src/fields/BaseRelationField.php#L675

public function afterElementSave(ElementInterface $element, bool $isNew)
    {
        // Skip if nothing changed, or the element is just propagating and we're not localizing relations
        /** @var Element $element */
        if (
            $element->isFieldDirty($this->handle) &&
            (!$element->propagating || $this->localizeRelations)
        ) {
            /** @var ElementQuery $value */
            $value = $element->getFieldValue($this->handle);

            // $id will be set if we're saving new relations
            if ($value->id !== null) {
                $targetIds = $value->id ?: [];
            } else {
                $targetIds = $this->_all($value, $element)->ids();
            }

            /** @var int|int[]|false|null $targetIds */
            Craft::$app->getRelations()->saveRelations($this, $element, $targetIds);

            // Reset the field value if this is a new element
            if ($isNew) {
                $element->setFieldValue($this->handle, null);
            }
        }

        parent::afterElementSave($element, $isNew);
    }

$targetIds is at the moment required to be an array making impossible pass a model instance to the relationship

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/fields/BaseRelationField.php at afterElementSave(), using the linked code to trace how $targetIds reaches saveRelations(). Confirm the expected relation input types and identify the relevant coverage before changing the save path. Done means a model instance can be passed for a relation without breaking array-based targets.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
backend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.