2012-11-17 10 views
9

Mi chiedo quale sia il modo migliore per creare un modulo che gestisca una relazione molti-a-molti con il campo extra in symfony2.Rendi una relazione molti-a-molti con campi aggiuntivi in ​​un modulo

Per l'esempio, diciamo che mi piacerebbe creare una funzione di notifica per gli utenti. Ho le entità User e Notification. Inoltre, per poter aggiungere parametri aggiuntivi nella relazione molti-a-molti tra entità, ho creato una terza entità UserNotification. Il parametro extra indica se la notifica è stata letta o meno dagli utenti.

* @ORM\Entity() */ 
class Notification 
{ 
    /** @Id @Column(type="integer") */ 
    private $id; 

    /** @OneToMany(targetEntity="UserNotification", mappedBy="notification") */ 
    private $usernotifications; 

    /** @Column() */ 
    private $message; 

    ... 
} 

* @ORM\Entity() */ 
class User 
{ 
    /** @Id @Column(type="integer") */ 
    private $id; 

    /** @OneToMany(targetEntity="UserNotification", mappedBy="user") */ 
    private $usernotifications; 

    /** @Column() */ 
    private $name; 

    ... 
} 

* @ORM\Entity() */ 
class UserNotification 
{ 
    /** @ManyToOne(targetEntity="User", inversedBy="usernotifications") 
    private $user; 

    /** @ManyToOne(targetEntity="Message", inversedBy="usernotifications") 
    private $message; 

    /** @Column(type="boolean") */ 
    private $isRead; 

    ... 
} 

In questo modo sono in grado di ottenere questo tipo di dati

 User 
+----+---------+ 
| id | name | 
+----+---------+ 
| 1 | John | 
| 2 | Paul | 
+----+---------+ 

     Notification 
+----+----------------------+ 
| id | message    | 
+----+----------------------+ 
| 1 | Cool stuff   | 
| 2 | Lorem ipsum   | 
+----+----------------------+ 

     UserNotification 
+---------+-----------------+---------+ 
| user_id | notification_id | isRead | 
+---------+-----------------+---------+ 
| 1  |    1 |  1 | 
| 2  |    1 |  0 | 
| 1  |    2 |  0 | 
| 2  |    2 |  1 | 
+---------+-----------------+---------+ 

Ok ora qui è il problema, come fare una forma che consente di inviare una notifica ad alcuni utenti? Con una classica relazione molti-a-molti non era un problema. Ho avuto un NotificationType con il seguente builder:

$builder->add('users', 'entity', array(
       'class' => 'User', 
       'property' => 'name', 
       'multiple' => 'true', 
      )) 
      ->add('message', 'text'); 

Ma dal momento che ho dovuto creare la UserNotification entità intermedia, non ho idea di come farlo. Grazie per il tuo aiuto;)

risposta

4

Ho fatto esattamente la stessa cosa. La mia entità InternalMessage è la tua Notification. Nella forma, users campo non è mappato (property_path è false) ed è convalidato utilizzando un abbonato:

public function buildForm(FormBuilder $builder, array $options) 
{ 
    $builder 
     ->add('title', 'text', array(
      'label' => 'Titolo *' 
     )) 
     ->add('content', 'textarea', array(
      'label' => 'Contenuto *' 
     )) 
     ->add('priority', new PriorityType(), array(
      'label' => 'Priorità *' 
     )) 
     ->add('users', 'entity', array(
      'label'   => 'Destinatari *', 
      'class'   => 'Acme\HelloBundle\Entity\User', 
      'property'  => 'select_label', 
      'multiple'  => true, 
      'expanded'  => true, 
      'property_path' => false, 
     )); 
    ; 

    $builder->addEventSubscriber(new AddUsersValidationSubscriber()); 
} 

Mentre nel mio controller, l'unica cosa che devo fare (ammesso che la forma è valido) è per creare una InternalMessageFeedback entità (lo stesso del UserNotification) ribalta ogni utente nel modello di modulo:

$message = new InternalMessage(); 
$form = $this->createForm(new InternalMessageType(), $message); 

// ... 

// The sender 
$message->setUser($this->getSecurityContext()->getToken()->getUser()); 

// Persist the inverse side 
$em = $this->getEntityManager(); 
$em->persist($message); 

// One feedback for each user 
/** @var $user \Acme\HelloBundle\Entity\User */ 
foreach($form->get('users')->getData() as $user) { 
    $feedback = new InternalMessageFeedback(); 

    // Se the message and user for current feedback 
    $feedback->setInternalMessage($message); 
    $feedback->setUser($user); 

    // Persist the owning side 
    $em->persist($feedback); 

    // Sync the inverse side 
    $message->addInternalMessageFeedback($feedback); 
} 

$em->flush(); 

Spero che questo aiuti :)

+0

Grazie per y la nostra risposta Gremo;) non ero a conoscenza della proprietà 'property_path'. E funziona come un fascino. –

Problemi correlati