Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony][Symfony2][SF2]Formularz w formularzu
Forum PHP.pl > Forum > PHP > Frameworki
skowron-line
Więc chce zrobić coś takiego
Mam 2 tabele
users i users_email_addresses
i teraz chce na stronie mieć 2 inputy
- nazwa użytkownika
- email użytkownika

I teraz tak stworzyłem sobie Entity
  1. class Users
  2. {
  3. /**
  4.   * @var integer
  5.   *
  6.   * @ORM\Column(name="id_users", type="smallint", nullable=false)
  7.   * @ORM\Id
  8.   * @ORM\GeneratedValue(strategy="IDENTITY")
  9.   */
  10. private $id;
  11.  
  12. /**
  13.   * @var string
  14.   *
  15.   * @ORM\Column(name="name", type="string", length=100, nullable=true)
  16.   */
  17. private $name;
  18. /**
  19.   *
  20.   * @var ArrayCollection
  21.   * @ORM\OneToMany(targetEntity="UsersEmailAddresses", mappedBy="users")
  22.   */
  23. private $email;

i
  1. class UsersEmailAddresses
  2. {
  3. /**
  4.   * @var integer
  5.   *
  6.   * @ORM\Column(name="id_users_email_adresses", type="smallint", nullable=false)
  7.   * @ORM\Id
  8.   * @ORM\GeneratedValue(strategy="IDENTITY")
  9.   */
  10. private $id;
  11.  
  12. /**
  13.   * @var string
  14.   *
  15.   * @ORM\Column(name="email", type="string", length=100, nullable=true)
  16.   */
  17. private $email;
  18.  
  19. /**
  20.   * @var type
  21.   *
  22.   * @ORM\ManyToOne(targetEntity="Users", inversedBy="email")
  23.   * @ORM\JoinColumn(name="users_id", referencedColumnName="id_users")
  24.   */
  25. private $users;


I teraz w deklaracji formularza mam coś takiego
  1. public function buildForm(FormBuilderInterface $builder, array $options)
  2. {
  3. $builder
  4. ->add('name')
  5. ->add('email', 'collection', array(
  6. 'type'=> new UsersEmailAddressesType(),
  7. ))
  8. ;
  9. }
  10.  
  11. public function setDefaultOptions(OptionsResolverInterface $resolver)
  12. {
  13. $resolver->setDefaults(array(
  14. 'data_class' => 'Test\UserBundle\Entity\Users',
  15. 'cascade_validation' => true
  16. ));
  17. }

Jako że przy dodawaniu nowego usera nie ma żadnego adresu email to pole input się nie wyświetla więc na hama dodałem (tak wiem że na stronie jest opcja dodawania pola przez JS)
  1. $email = new \Test\UserBundle\Entity\UsersEmailAddresses;
  2. $formEmail = $this->createForm(new \Test\UserBundle\Form\UsersEmailAddressesType, $email);
  3.  
  4. return array(
  5. 'email_form' => $formEmail->createView(),
  6. 'entity' => $entity,
  7. 'form' => $form->createView(),
  8. );


I wszystko było by ok gdyby nie to że po wysłaniu formularza dostaje komunikat
Cytat
Catchable Fatal Error: Argument 1 passed to Test\UserBundle\Entity\Users::setEmail() must be an instance of Test\UserBundle\Entity\UsersEmailAddresses, array given..

No i teraz pytanie brzmi czy dobrze się do tego zabrałem questionmark.gif Bo jak mam przekazać obiekt UsersEmailAddresses w sytuacji kiedy chce aby najpierw user wpadl do bazy a pozniej adres email z id_users wczesniej dodanego.

Chyba że to działa
insert (email)
id = insert (users)
update (email) set users_id = id
(a tak podejrzewam że to działa)

Ps Sorki za może głupie pytanie ale z ORM do tej pory miałem nie wiele wspólnego.
domo
Gdy tworzysz formulasz UsersType z polem

('email', 'collection', array(
'type'=> new UsersEmailAddressesType(),
))

do tego pola przypisywane są powiązane Entity UserEmailAddresses. Gdybyś miał juz UserEmailAddresses w relacji do Users, widniałyby w formularzu.
Jako, że ich fizycznie nie ma, zatem ich nie przypisuje.

Rozwiązanie brzydkie:

Zanim utworzysz formularz usersType, stwórz entity Users, któremu dodasz entity UserEmailAddresses
$user = new Users();
$user->addUserEmailAddresses(new UserEmailAddresses())
$form = $this->createForm(new UserType(), $user);

wtedy powinieneć zobaczyć chciane pole Email smile.gif
skowron-line
Ok wszystko fajnie pole się pojawia, formularz leci ale dane do
users się zapisują
users-email-addresses się zapisują ale bez users_id
  1. $entity = new Users();
  2. $form = $this->createForm(new UsersType(), $entity);
  3. $form->bind($request);
  4.  
  5. if ($form->isValid()) {
  6.  
  7. $em = $this->get('doctrine')->getManager();
  8. $em->persist($entity);
  9. $em->flush();
  10.  
  11. return $this->redirect($this->generateUrl('users_show', array('id' => $entity->getId())));
  12. }

Czy coś tu jeszcze trzeba dopisać questionmark.gif
minolone
Popatrz na to:
http://adurieux.blogspot.com/2011/10/oneto...trine2-and.html
masz tam dokladnie pokazane jak powinna wygladac relacja, robilem relacje tak samo jak tam jest pokazane i zawsze działały, włącznie z SonataAdminBundle nidy nie było problemów.

Moim zdaniem brakuje Ci w entity konstruktora z ArrayCollection i nie zapomnij o setterach z instancją do klasy w relacji,

pozdrawiam
skowron-line
Już nie moge gapie się w to i gapie i nie moge znaleźć błędu
  1. <?php
  2.  
  3. namespace Test\UserBundle\Entity;
  4.  
  5. use Doctrine\ORM\Mapping as ORM;
  6. use Symfony\Component\Validator\Constraints as Assert;
  7. use Doctrine\Common\Collections\ArrayCollection;
  8.  
  9. /**
  10.  * Users
  11.  *
  12.  * @ORM\Table(name="users")
  13.  * @ORM\Entity
  14.  */
  15. class Users
  16. {
  17. /**
  18.   * @var integer
  19.   *
  20.   * @ORM\Column(name="id", type="smallint", nullable=false)
  21.   * @ORM\Id
  22.   * @ORM\GeneratedValue(strategy="IDENTITY")
  23.   */
  24. private $id;
  25.  
  26. /**
  27.   * @var string
  28.   *
  29.   * @ORM\Column(name="name", type="string", length=100, nullable=true)
  30.   * @Assert\NotBlank()
  31.   */
  32. private $name;
  33. /**
  34.   *
  35.   * @var ArrayCollection
  36.   * @ORM\OneToMany(targetEntity="UsersEmailAddresses", mappedBy="users", cascade={"persist", "remove"})
  37.   */
  38. private $email;
  39.  
  40. public function __construct()
  41. {
  42. $this->email = new ArrayCollection();
  43. }
  44. /**
  45.   * Get idUsers
  46.   *
  47.   * @return integer
  48.   */
  49. public function getId()
  50. {
  51. return $this->id;
  52. }
  53.  
  54. /**
  55.   * Set name
  56.   *
  57.   * @param string $name
  58.   * @return Users
  59.   */
  60. public function setName($name)
  61. {
  62. $this->name = $name;
  63.  
  64. return $this;
  65. }
  66.  
  67. /**
  68.   * Get name
  69.   *
  70.   * @return string
  71.   */
  72. public function getName()
  73. {
  74. return $this->name;
  75. }
  76.  
  77. public function addEmail(\Test\UserBundle\Entity\UsersEmailAddresses $email)
  78. {
  79. $this->email = $email;
  80. $email->setUsers($this);
  81. return $this;
  82. }
  83.  
  84.  
  85. public function getEmail()
  86. {
  87. return $this->email;
  88. }
  89.  
  90. }

  1. <?php
  2.  
  3. namespace Test\UserBundle\Entity;
  4.  
  5. use Doctrine\ORM\Mapping as ORM;
  6. use Symfony\Component\Validator\Constraints as Assert;
  7.  
  8. /**
  9.  * UsersEmailAddresses
  10.  *
  11.  * @ORM\Table(name="users_email_addresses")
  12.  * @ORM\Entity
  13.  */
  14. class UsersEmailAddresses
  15. {
  16. /**
  17.   * @var integer
  18.   *
  19.   * @ORM\Column(name="id", type="smallint", nullable=false)
  20.   * @ORM\Id
  21.   * @ORM\GeneratedValue(strategy="IDENTITY")
  22.   */
  23. private $id;
  24.  
  25. /**
  26.   * @var string
  27.   *
  28.   * @ORM\Column(name="email", type="string", length=100, nullable=true)
  29.   * @Assert\NotBlank()
  30.   */
  31. private $email;
  32.  
  33. /**
  34.   * @var type
  35.   *
  36.   * @ORM\ManyToOne(targetEntity="Users", inversedBy="email")
  37.   * @ORM\JoinColumn(name="users_id", referencedColumnName="id")
  38.   */
  39. private $users;
  40. /**
  41.   * Get idUsersEmailAdresses
  42.   *
  43.   * @return integer
  44.   */
  45. public function getId()
  46. {
  47. return $this->id;
  48. }
  49.  
  50. /**
  51.   * Set email
  52.   *
  53.   * @param string $email
  54.   * @return UsersEmailAddresses
  55.   */
  56. public function setEmail($email)
  57. {
  58. $this->email = $email;
  59.  
  60. return $this;
  61. }
  62.  
  63. /**
  64.   * Get email
  65.   *
  66.   * @return string
  67.   */
  68. public function getEmail()
  69. {
  70. return $this->email;
  71. }
  72.  
  73. public function setUsers(\Test\UserBundle\Entity\Users $users)
  74. {
  75. $this->users = $users;
  76.  
  77. return $this;
  78. }
  79.  
  80. public function getUsers()
  81. {
  82. return $this->users;
  83. }
  84. }

i kontroler jak w poprzednim poscie.

I nadal się nie zapisuje users_id w tabeli users_email_adresses
Crozin
1. Po pierwsze nazewnictwo. Dlaczego do reprezentacji pojedynczego użytkownika używasz nazwy Users (zamiast User), zaś do kolekcji maili email zamiast emails? Przecież to nie ma najmniejszego sensu, a kod bardzo źle się czyta.
2. Typ collection domyślnie pozwala jedynie na edycje istniejących elementów kolekcji, nie ich dodawanie czy kasowanie. Musisz ustawić opcje allow_add i allow_delete na TRUE.
3. Podstawowa lektura: dokumentacja typu collection.
4. Możesz też być zainteresowany typem entity oraz How to Embed a Collection of Forms.
skowron-line
1. Tak wiem piszesz mi to za każdym razem smile.gif
2.
  1. $builder
  2. ->add('name', 'text', array('required' => false))
  3. ->add('email', 'collection', array(
  4. 'type' => new UsersEmailAddressesType(),
  5. 'allow_add' => true
  6. ))
  7. ;

Jak to zrobić żeby z jednego formularza wrzucić do dwóch tabel przyczym do 2 ma trafiać id z pierwszej ?
3, 4 Czytałem

EDIT:
Rozwiązałem to tak, nie wiem czy to najlepsze rozwiązanie ale działa
  1. $em = $this->get('doctrine')->getManager();
  2. $em->persist($entity);
  3. $em->flush();
  4.  
  5. $emails = $entity->getEmail();
  6. // foreach
  7. $email = $em->getRepository('UserBundle:UsersEmailAddresses')->findById($emails[0]->getId());
  8.  
  9. $email[0]->setUsers($entity);
  10. $em->persist($email[0]);
  11. $em->flush();
  12. // endforeach
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.