2013-02-26 12 views
5

Sto riscontrando un problema di progettazione nel mio progetto, relativo a dove mettere una logica aziendale.Symfony2: l'approccio migliore per utilizzare la logica business (repository) nell'entità o controller

Ho tre entità, Evento, TicketOrder e Ticket. Un evento ha un sacco di TicketOrders e un TicketOrder ha molti biglietti.

Nel mio modello, devo mostrare quanti biglietti ha un evento. Ho pensato all'approccio migliore per raggiungere questo obiettivo e non ho trovato una buona soluzione. Ho provato questo:

1) Creare un ticket ticket 'membro privato nell'entità Event, con metodo setTicketsCount e getTicketsCount. Creare un metodo 'loadTicketsCount' con LifeCycleCallback 'PostLoad', per accedere al metodo TicketRepository 'findByEvent'. Questo era impossibile perché non posso accedere al repository in una classe di entità.

2) Nell'azione che verrà utilizzata per visualizzare l'evento, posso accedere all'archivio dei ticket e impostare manualmente la proprietà 'ticketCount' dell'evento. Non so se è un buon approccio perché se la mia azione è elencare un sacco di eventi dovrò effettuare il ciclo su tutti gli eventi e fare una chiamata al repository per ciascuno di questi.

Io davvero non conosco l'approccio migliore per raggiungere questo obiettivo e apprezzerò davvero se qualcuno mi può aiutare.

Grazie! ;)

+0

Vuoi il numero di biglietti totali? {{event.tickets | length}} restituisce il numero totale di ticket associati a determinati eventi. –

+0

Grazie per la tua risposta, artworkad. l'oggetto evento non ha membri 'ticket', i ticket beacause sono correlati ai ticketorders e 'ticketorders' è correlato a 'evento'. Inoltre, non voglio usare il metodo di lunghezza ramoscello perché penso che sia inefficiente. Penso che sia meglio fare una query COUNT in repository o qualcosa del genere. Ho ragione io? –

risposta

2

Quando si utilizzano i metodi findAll, findBy o findBy * del repository di entità doctrine, viene restituito un semplice array php contenente gli oggetti entity.

La classe dell'array implementa un'interfaccia numerabile. Quindi, utilizzando ramoscelli filtro lunghezza

{{ ticketOrder.tickets|length }} 

si esegue una semplice php count() sulla matrice.

In realtà ora ha senso eseguire una query di conteggio, perché il risultato è già presente in memoria. Quindi sembra più efficiente contare il risultato e recuperarlo dalla memoria, perché quando si accede alle associazioni vengono caricati completamente nella memoria.


Tuttavia le associazioni tra entità possono diventare piuttosto grandi. Quindi immagina di avere associazioni con centinaia di migliaia di entità. Non sarete quei soggetti a essere caricati tutti insieme e tenuti in memoria tutto il tempo. Quindi in Doctrine 2.1 puoi annotare un'associazione come Extra Lazy. Se lo fai nel tuo caso, viene eseguita una query di conteggio quando chiami il filtro di ramoscello sopra. Ma il risultato non è tenuto in memoria.

http://docs.doctrine-project.org/en/2.0.x/tutorials/extra-lazy-associations.html


Secondo il vostro ultimo commento:

riesco a immaginare un modo per fare questo. In un modello che si può chiamare l'azione di un controller con la dichiarazione di rendering come

{% render YourMainBundle:getTickets with { 'event_id' : event.id } %} 

e in questa azione si può chiamare una query che cerca tutti i biglietti relativi alla determinato evento. Questa azione deve restituire HTML, ad es. un modello pieno di dati.

+0

Grazie artwork. Le associazioni Lazy extra aiuterebbero molto a non caricare tutti i ticket nella memoria. Ma continuo ad avere un problema con le entità correlate indirette. Come ho detto, gli eventi hanno i biglietti che hanno i biglietti. Come posso ottenere, in modo modello, tutti i ticket di un evento? Non voglio scorrere su ogni ticketorder di eventi in ramoscello e poi scorrere su ogni ticket biglietto. Voglio davvero un modo efficiente di avere 'code' {{event.tickets}}' code' ma non so come farlo. Riempiendolo in controller o creando qualcosa di simile, i repository e le entità? Grazie! –

+0

Ok ho modificato la mia risposta –

+0

Bella risposta, artworkad. Non ho mai pensato di usare render per chiamare le azioni del controller nei template. Ma un ultimo commento: ho davvero bisogno di un modo per avere un campo "ticketCount" sempre inserito negli oggetti eventi. È possibile avere un tipo di metodo PostLoad che viene sempre eseguito quando l'oggetto viene richiamato dal database e in questo metodo viene chiamato un metodo di repository che esegue la query COUNT? Non riesco a utilizzare lyfeciclecallback perché non posso chiamare la business logic nelle entità. = \ Qualsiasi ideia? Saluti! –