2016-06-11 60 views
1

想象一下这2个实体:多对一形式创建链接的对象

Article 
    title 
    description 
    category <- ManyToOne 

Category 
    name 

说,我们需要管理与表并附上该类别的文章。

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

这一个将允许我从现有的类别中选择。

现在我想能够根据需要创建类别。

Title [     ] 
Description 
[       ] 
[       ] 
Category [     ] 

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

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

我该如何做到可重复使用?

回答

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(); 
//... 
+0

实际上,这不适用于集合,如果我们输入多个具有相同新“类别”的“Article” –

0

建议您对您的类别执行“if”操作。 当你检查你的表单提交是否有效并提交时,获取'类别'数据,如果不存在,则将其作为新类别进行保存,然后查询文章。

的代码可能是这样的:

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... 
    } 

希望你明白我的意思。上面的代码比较简单,因为这样你就可以用相同的形式创建类别。

+0

谢谢您的回答。我忘了提及我正在寻找一种可重复使用的解决方案,可能涉及到“DataTransformer”或其他东西。因为我将在我的几个控制器中使用它 –