繁体   English   中英

Symfony Form CollectionType,带有新的/现有实体的API帖子

[英]Symfony Form CollectionType with API post of new/existing entities

构建一个内部API端点,该端点允许另一个服务更新用户的特定字段(由电子邮件地址标识)。 如果用户不存在,则需要创建它。

如果仅提交新用户,该代码将运行良好。

这是对API端点的POST请求。

[
    {
        "email":"existing@user.com",
        "favouriteFood": "pizza"
    },
    {
        "email":"new@user.com",
        "favouriteFood": "sweets"
    }
]

控制器动作

public function postUsersAction(Request $request)
{
    $form = $this->createForm(UserCollectionType::class);
    $form->submit(['users' => json_decode($request->getContent(), true)], true);

    if (!$form->isValid()) {
        return $form;
    }

    /** @var User $user */
    foreach ($form->getData()['users'] as $user) {
        $this->userManager->updateUser($user);
    }

    $this->em->flush();

    return $form->getData()['users'];
}

UserCollectionType

class UserCollectionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('users', 'collection', [
            'allow_add' => true,
            'by_reference' => false,
            'type' => UserType::class
        ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'csrf_protection' => false,
            'cascade_validation' => true
        ]);
    }

    public function getBlockPrefix()
    {
        return '';
    }
}

用户类型

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email')
            ->add('favouriteFood', TextType::class);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class,
            'validation_groups' => ['user_api'],
            'cascade_validation' => true
        ]);
    }
} 

我如何更新上面的代码,以便它将首先检查用户是否存在,否则将继续创建一个新代码,该代码当前的工作方式。

我以为可以使用DataTransformer,但不完全是这样。

编辑:由ShylockTheCamel建议的解决方案

控制器内部。

$post = json_decode($request->getContent(), true);
$users = [];

foreach ($post as $userRaw) {
    $user = $this->em->findOneBy($userRaw['email']); // example search logic in the DB

    if (!$user) {
        $user = new User();
    }

    $users[] = $user;
}

$form = $this->createForm(UserCollectionType::class, $users);
$form->submit(['users' => $post], true);

如果我理解正确,那么当您进入foreach循环时,您的用户实体就存在了。 因此,您必须在表单创建过程中创建它们。 在那种情况下,为什么不检查您的表单验证器中某个用户的存在?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM