Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GraphQL] How to create relation objects in mutation? #3420

Closed
oleg-brizy opened this issue Feb 29, 2020 · 1 comment
Closed

[GraphQL] How to create relation objects in mutation? #3420

oleg-brizy opened this issue Feb 29, 2020 · 1 comment

Comments

@oleg-brizy
Copy link

oleg-brizy commented Feb 29, 2020

I want to create child entities (fields) in the same mutation

mutation {
  createCollectionType (input: {
      title: "Hello world",
      fields: [
        {
          title: "Field 1",
          type: text
        }
      ]
    }
  ) {
    collectionType { id }
  }
}

but I get error

{
  "errors": [
    {
      "debugMessage": "Nested documents for attribute \"fields\" are not allowed. Use IRIs instead.",
    }
  ]
}

I can't and don't want to use IRIs because it will require multiple mutations (server requests).

• Entity/Resource

/**
 * @ApiResource(
 *  graphql={
 *     "create"={
 *         "mutation"=CollectionTypeMutationResolver::class,
 *         "args"={
 *             "title"={"type"="String!"},
 *             "fields"={"type"="[CollectionTypeFieldInput!]"},
 *         },
 *     }
 *   }
 * )
 *
 * @ORM\Entity(...)
 */
class CollectionType
{
    ...

    /**
     * @ORM\OneToMany(targetEntity="CollectionTypeField", mappedBy="collectionType", cascade={"persist", "remove"})
     * @ORM\OrderBy({"priority": "DESC"})
     *
     * @Assert\Valid()
     */
    private $fields;

CollectionTypeMutationResolver is empty (just return).

collectionTypeFieldInput type (not so relevant)

final class CollectionTypeFieldInputType extends InputObjectType implements TypeInterface
{
    public function __construct(array $config = [])
    {
        $config['fields'] = [
            'title' => Type::nonNull(Type::string()),
            'type' => Type::nonNull(MyTypeRegistry::collectionFieldType()),
        ];

        parent::__construct($config);
    }
}

I tried to rename arg to "createFields" to not match entity property, to bypass the "Nested documents are not allowed".

```php
/**
 * @ApiResource(
 *  graphql={
 *     "create"={
 *         "args"={
 *             "createFields"={"type"="[CollectionTypeFieldInput!]"},
 *         },
 *     }
 *   }
 * )
 */

Then in resolver to populate entity fields property from createFields mutation arg

final class CollectionTypeMutationResolver implements MutationResolverInterface
{
    public function __invoke($item, array $context)
    {
        $fields = new ArrayCollection();
        foreach ($context['args']['input']['createFields'] as $fieldArgs) { print_r($fieldArgs);
            $field = new CollectionTypeField();
            $field->setCollectionType($item);
            $field->setTitle($fieldArgs['title']);
            $field->setType($fieldArgs['type']);
            if (isset($fieldArgs['priority'])) {
                $field->setPriority($fieldArgs['priority']);
            }
            if (isset($fieldArgs['required'])) {
                $field->setRequired($fieldArgs['required']);
            }
        }
        $item->setFields($fields);

        return $item;
    }
}

The entity is created but child entities are not validated and not created. Seems like resolver is executed right before save after $item was persisted (I have read the docs but still don't understand when exactly, after/before what stage, the resolver is executed).


How to create a mutation that creates nested relations (one/any level) ?

@oleg-brizy
Copy link
Author

#3258 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant