ManyToOne表单创建链接对象

时间:2016-06-11 17:43:12

标签: doctrine symfony

想象一下这两个实体:

Article
  title
  description
  category <- ManyToOne

Category
  name

假设我们需要管理一个带有表单和附加类别的文章。

$builder
    ->add('name')
    ->add('description')
    ->add('category')

这个允许我从现有类别中进行选择。

现在我希望能够在需要时创建类别。

Title    [                 ]
Description
[                          ]
[                          ]
Category [                 ]

类别字段将是一个自由文本框 如果文本对应于没有类别,则将创建并附加新文本 我尝试了一些DataTransformer而没有运气

我需要一个可重用的解决方案来管理它,因为我需要将其特别以另一种形式嵌入它作为集合。

我怎样才能重复使用?

2 个答案:

答案 0 :(得分:0)

建议你做一个&#34; if&#34;在你的类别上。 当您检查表单提交是否有效并已提交时,请获取“&#39;类别&#39;数据,如果不存在,则将其保留为新类别,然后查询文章。

代码可能是这样的:

if ($form-isSubmitted() && $form->isValid()){
    $catName = $form->get('category')->getData();   // Get category.

    // Query if it exists.
    $qb = $em->createQueryBuilder();
    $qb->select('c')
        ->from('AppBundle:Category', 'c')
        ->where('c.name = :catName')
        ->setParameter('catName', $catName);
    $cat_results = $qb->getQuery()->setMaxResults(1)->getOneOrNullResult();

    if ($cat_results == null){
        $newCat = new Category();
        $newCat()->setname($catName);
        $em->persist($newCat);
        $em->flush();
    }
    else{
        ...
        \\ Render your form etc...
    }

希望你明白了。上面的代码更简单,因为您可以使用相同的形式创建类别。

答案 1 :(得分:0)

以下是我最后使用DataTransformer

的内容

我的ArticleType

class ArticleType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('description')
            ->add('category', CategoryType::class)
//...

新的CategoryType课程:

class CategoryType extends AbstractType
{
    protected $myService;

    public function __construct(MyService $myService)
    {
        $this->myService = $myService;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new CategoryTransformer($this->myService);
        $builder->addModelTransformer($transformer);
    }
}

注册为服务

app.form.category_type:
    class: AppBundle\Form\CategoryType
    arguments: ['@app.my.service']
    tags:
        - { name: form.type }

最后是变压器:

class CategoryTransformer implements DataTransformerInterface
{
    // ...MyService initialization...

    public function transform($category)
    {
        if (null === $category) {
            return '';
        }
        return $category->getName();
    }

    public function reverseTransform($categoryName)
    {
        if (!$categoryName) {
            return null;
        }
        $category = $this->myService->getOrCreateCategoryFromName($categoryName);

        if (null === $category) {
            throw new TransformationFailedException();
        }

        return $category;
    }
}

MyService负责使用实体管理器获取或创建具有给定名称的类别。

相当一些代码行但是一旦完成,无论我在哪里使用我的表单,都可以用简单的标准方式处理:

$articleForm = $this->createForm(ArticleType::class, $article);
$articleForm->handleRequest($request);

if ($articleForm->isValid()) {
    $em->persist($article);
    $em->flush();
//...