@@ -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 In addition to telling the field to accept any number of submitted objects, the
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- Toget the new tagsto 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+ Tosave the new tagswith 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 formframework 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 formtype 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();