@@ -53,11 +53,6 @@ objects. Start by creating a simple ``Task`` class::
5353 { 
5454 return $this->tags; 
5555 } 
56- 
57-  public function setTags(ArrayCollection $tags) 
58-  { 
59-  $this->tags = $tags; 
60-  } 
6156 } 
6257
6358.. note ::
@@ -240,9 +235,9 @@ zero tags when first created).
240235
241236 <!-- ... -->
242237
243- When the user submits the form, the submitted data for the ``Tags `` fields
244- are  used to construct an ArrayCollection of ``Tag `` objects, which is then
245- set  on the ``tag `` field of the ``Task `` instance.
238+ When the user submits the form, the submitted data for the ``Tags `` fields are 
239+ used to construct an `` ArrayCollection ``  of ``Tag `` objects, which is then set 
240+ on the ``tag `` field of the ``Task `` instance.
246241
247242The ``Tags `` collection is accessible naturally via ``$task->getTags() ``
248243and can be persisted to the database or used however you need.
@@ -286,7 +281,6 @@ add the ``allow_add`` option to your collection field::
286281 // src/Acme/TaskBundle/Form/Type/TaskType.php 
287282
288283 // ... 
289-   
290284 use Symfony\Component\Form\FormBuilderInterface; 
291285
292286 public function buildForm(FormBuilderInterface $builder, array $options) 
@@ -296,18 +290,59 @@ add the ``allow_add`` option to your collection field::
296290 $builder->add('tags', 'collection', array( 
297291 'type' => new TagType(), 
298292 'allow_add' => true, 
299-  'by_reference' => false, 
300293 )); 
301294 } 
302295
303- Note that ``'by_reference' => false `` was also added. Normally, the form
304- framework would modify the tags on a `Task ` object *without * actually
305- ever calling `setTags `. By setting :ref: `by_reference<reference-form-types-by-reference> `
306- to `false `, `setTags ` will be called. This will be important later as you'll
307- see.
296+ Now that the form type knows tags can be added, the ``Tasks `` class needs to
297+ add methods to make editing the tags possible. This is done by creating an
298+ "adder". In this case, the adder will be ``addTag ``::
299+ 
300+  // src/Acme/TaskBundle/Entity/Task.php 
301+  namespace Acme\TaskBundle\Entity; 
302+ 
303+  // ... 
304+  class Task 
305+  { 
306+  // ... 
307+ 
308+  public function addTag($tag) 
309+  { 
310+  $this->tags->add($tag); 
311+  } 
312+ 
313+  public function removeTag($tag) 
314+  { 
315+  // ... 
316+  } 
317+  } 
318+ 
319+ But, the form type will still use ``getTags `` now. You need to set the
320+ ``by_reference `` option to ``false ``, otherwise the form type will get the
321+ object by using the getter and change that object.
322+ 
323+ .. caution ::
324+ 
325+  If no ``addTag `` **and ** ``removeTag `` method is found, the form will
326+  still ``setTag `` when setting ``by_reference `` to ``false ``. You'll learn
327+  more about the ``removeTag `` method later in this article.
328+ 
329+ .. code-block :: php 
330+ 
331+  // src/Acme/TaskBundle/Form/Type/TaskType.php 
332+ 
333+  // ... 
334+  public function buildForm(FormBuilderInterface $builder, array $options) 
335+  { 
336+  // ... 
337+ 
338+  $builder->add('tags', 'collection', array( 
339+  // ... 
340+  'by_reference' => false, 
341+  )); 
342+  } 
308343
309344
310- ``allow_add `` also makes a "prototype" variable available to you. This "prototype"
345+ ``allow_add `` also makes a * "prototype" *  variable available to you. This "prototype"
311346is a little "template" that contains all the HTML to be able to render any
312347new "tag" forms. To render it, make the following change to your template:
313348
@@ -321,7 +356,9 @@ new "tag" forms. To render it, make the following change to your template:
321356
322357 .. code-block :: html+php 
323358
324-  <ul class="tags" data-prototype="<?php echo $view->escape($view['form']->row($form['tags']->vars['prototype'])) ?>">
359+  <ul class="tags" data-prototype="<?php
360+  echo $view->escape($view['form']->row($form['tags']->vars['prototype']))
361+  ?>">
325362 ...
326363 </ul>
327364
@@ -430,13 +467,14 @@ into new ``Tag`` objects and added to the ``tags`` property of the ``Task`` obje
430467
431468.. sidebar :: Doctrine: Cascading Relations and saving the "Inverse" side 
432469
433-  To get  the new tags to save in  Doctrine, you need to consider a couple
434-  more  things. First, unless you iterate over all of the new ``Tag `` objects
435-  and  call ``$em->persist($tag) `` on each, you'll receive an error from
470+  To save  the new tags with  Doctrine, you need to consider a couple more 
471+  things. First, unless you iterate over all of the new ``Tag `` objects and 
472+  call ``$em->persist($tag) `` on each, you'll receive an error from
436473 Doctrine:
437474
438-  A new entity was found through the relationship `Acme\TaskBundle\Entity\Task#tags `
439-  that was not configured to cascade persist operations for entity...
475+  A new entity was found through the relationship
476+  ``Acme\TaskBundle\Entity\Task#tags `` that was not configured to
477+  cascade persist operations for entity...
440478
441479 To fix this, you may choose to "cascade" the persist operation automatically
442480 from the ``Task `` object to any related tags. To do this, add the ``cascade ``
@@ -492,29 +530,25 @@ into new ``Tag`` objects and added to the ``tags`` property of the ``Task`` obje
492530 of the relationship is modified.
493531
494532 The trick is to make sure that the single "Task" is set on each "Tag".
495-  One easy way to do this is to add some extra logic to ``setTags ()
496-  which is called by the form framework  since :ref: ` by_reference<reference-form-types-by-reference>  ` 
497-  is set to  ``false ``::
533+  One easy way to do this is to add some extra logic to ``addTag ()
534+  which is called by the form type  since `` by_reference `` is set to 
535+  ``false ``::
498536
499537 // src/Acme/TaskBundle/Entity/Task.php 
500538
501539 // ... 
502- 
503-  public function setTags(ArrayCollection $tags) 
540+  public function addTag(ArrayCollection $tag) 
504541 { 
505-  foreach ($tags as $tag) { 
506-  $tag->addTask($this); 
507-  } 
542+  $tag->addTask($this); 
508543
509-  $this->tags = $tags ; 
544+  $this->tags->add($tag) ; 
510545 } 
511546
512547 Inside ``Tag ``, just make sure you have an ``addTask `` method::
513548
514549 // src/Acme/TaskBundle/Entity/Tag.php 
515550
516551 // ... 
517- 
518552 public function addTask(Task $task) 
519553 { 
520554 if (!$this->tasks->contains($task)) { 
@@ -523,7 +557,7 @@ into new ``Tag`` objects and added to the ``tags`` property of the ``Task`` obje
523557 } 
524558
525559 If you have a ``OneToMany `` relationship, then the workaround is similar,
526-  except that you can simply call ``setTask `` from inside ``setTags ``.
560+  except that you can simply call ``setTask `` from inside ``addTag ``.
527561
528562.. _cookbook-form-collections-remove :
529563
@@ -538,20 +572,31 @@ Start by adding the ``allow_delete`` option in the form Type::
538572 // src/Acme/TaskBundle/Form/Type/TaskType.php 
539573
540574 // ... 
541-  use Symfony\Component\Form\FormBuilderInterface; 
542- 
543575 public function buildForm(FormBuilderInterface $builder, array $options) 
544576 { 
545-  $builder->add('description');  
577+  // ...  
546578
547579 $builder->add('tags', 'collection', array( 
548-  'type' => new TagType(), 
549-  'allow_add' => true, 
580+  // ... 
550581 'allow_delete' => true, 
551-  'by_reference' => false, 
552582 )); 
553583 } 
554584
585+ Now, you need to put some code into the ``removeTag `` method of ``Task ``::
586+ 
587+  // src/Acme/TaskBundle/Entity/Task.php 
588+ 
589+  // ... 
590+  class Task 
591+  { 
592+  // ... 
593+ 
594+  public function removeTag($tag) 
595+  { 
596+  $this->tags->removeElement($tag); 
597+  } 
598+  } 
599+ 
555600Templates Modifications
556601~~~~~~~~~~~~~~~~~~~~~~~ 
557602
@@ -604,11 +649,11 @@ the relationship between the removed ``Tag`` and ``Task`` object.
604649.. sidebar :: Doctrine: Ensuring the database persistence 
605650
606651 When removing objects in this way, you may need to do a little bit more
607-  work to ensure that the relationship between the Task and the removed Tag 
608-  is properly removed.
652+  work to ensure that the relationship between the `` Task ``  and the removed
653+  `` Tag ``  is properly removed.
609654
610655 In Doctrine, you have two side of the relationship: the owning side and the
611-  inverse side. Normally in this case you'll have a ManyToMany relation
656+  inverse side. Normally in this case you'll have a `` ManyToMany ``  relation
612657 and the deleted tags will disappear and persist correctly (adding new
613658 tags also works effortlessly).
614659
@@ -623,7 +668,6 @@ the relationship between the removed ``Tag`` and ``Task`` object.
623668 // src/Acme/TaskBundle/Controller/TaskController.php 
624669
625670 // ... 
626- 
627671 public function editAction($id, Request $request) 
628672 { 
629673 $em = $this->getDoctrine()->getManager(); 
0 commit comments