Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1
    Utente di HTML.it L'avatar di Fractals87
    Registrato dal
    Apr 2008
    Messaggi
    1,202

    Symfony 2 Form/Choices/Tabella Relazione

    Ciao a tutti,

    Sto cercando di costruire la form dell'entità book in relazione con category.
    Mi sono arenato nel repository con query builder per ottenere l'array delle categorie da passare al metodo createFormBuilder.
    Vi illustro il panorama per vedere se è anche la strada giusta :

    Metodo createAction() di Book :
    Codice PHP:
        public function createAction(Request $request)
        {
            
    $book = new Book();
        
        
    $category $this->getDoctrine()
                 ->
    getRepository('AcmeDemoBundle:Category')
                 ->
    findAllReturnArray();
    echo 
    $category;exit();
            
    $form $this->createFormBuilder($book)
                         ->
    add('title''text')
                         ->
    add('isbn''text')
                         ->
    add('author''text')
                         ->
    add('description''textarea')
                         ->
    add('price''text')
                 ->
    add('categoryId''choice', array('choices'   => $category,
                                   
    'required'  => false,
                                  )
                  )
                         ->
    add('save''submit', array('label' => 'Crea libro'))
                         ->
    getForm();
     
            
    $form->handleRequest($request);
     
            if (
    $form->isValid()) {
                
    //inserisco manualmente l'autore per semplificare l'esempio
                
    $em $this->getDoctrine()->getManager();
                
    //$category = $em->getRepository('AcmeDemoBundle:Category')->find(1);
                //$book->setCategoryId($category);
     
                
    $em->persist($book);
                
    $em->flush();
     
                return 
    $this->redirect($this->generateUrl('_book'));
            }
     
            return 
    $this->render(
                
    'AcmeDemoBundle:Book:create.html.twig',
                array(
                    
    'form' => $form->createView()
                )
            );    
        } 
    Io dovrei ottenere un array da passare al metodo add choice per poter costruire la mia select option.
    Per fare ciò mi pare di aver capito che la strada migliore sia creare un metodo apposta nel repository :

    Metodo findAllReturnArray entity Category :
    Codice PHP:
        public function findAllReturnArray()
        {

            try {
            
    $query $this->createQueryBuilder('c')
                  ->
    select('c')
                  ->
    from('Category''c')
                  ->
    getQuery()
                  ->
    getResult(Query::HYDRATE_ARRAY);

                return 
    $query;
            } catch (\
    Doctrine\ORM\NoResultException $e) {
                return 
    null;
            }
        } 
    Solo che nn c'è verso di costruire questa query anche da documentazione doctrine non riesco a capire come usare il metodo query builder.

    Ottengo il seguente errore :

    [Semantical Error] line 0, col 49 near 'Category c': Error: Class 'Category' is not defined.

    Sia la tabella che l'entità ci sono e le uso con successo tramite i metody getEntityManager presenti nel repository book (Non so se questa ultima info può essere d'aiuto).

    Grazie mille a tutti
    Che mestiere difficile.....essere da soli ancora di più

  2. #2
    Utente di HTML.it L'avatar di Fractals87
    Registrato dal
    Apr 2008
    Messaggi
    1,202
    Posto la soluzione trovata nella speranza che sia di aiuto ad qualcuno d'altro.
    Anche se si utilizza il querybuilder, è necessario specificare la entity.
    di conseguenza era necessario costruire il metodo nel repository in questo modo :

    Codice PHP:
        public function findAllReturnArray()
        {
            try {
            
    $categorie $this->createQueryBuilder('test')
                  ->
    select('c.id,c.name')
                  ->
    from('AcmeDemoBundle:Category''c')
                  ->
    getQuery()
                  ->
    getResult(Query::HYDRATE_ARRAY);
            foreach(
    $categorie as $categoria){
            
    $arrCat[$categoria['id']] = $categoria['name'];
            }        
            
    //dump($arrCat);exit();
                
    return $arrCat;
            } catch (\
    Doctrine\ORM\NoResultException $e) {
                return 
    null;
            }
        } 
    E' stato necessario inoltre adattare l'array, in modo che fosse correttamente interpretato dal metodo add per il campo choise.

    Soluzione sicuramente più elegante sarebbe stata usare i campo entity, ma per ora non ci sono riuscito, in pratica dovrebbe costruire una select option a fronte di un array entity fornito.

    http://symfony.com/it/doc/current/re...es/entity.html
    Che mestiere difficile.....essere da soli ancora di più

  3. #3
    cmq al tipo choice puoi passare anche un array di oggetti entità, così da evitarti qualche rottura di scatole
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  4. #4
    ad esempio

    Codice PHP:

    public function buildForm(FormBuilderInterface $builder, array $options)
        {
    .....

          
    $builder->add('users','entity',[
                
    'required' => false,
                
    'class' => 'EntityBundle:User',
                
    'property' => 'email',
                
    'choices' => $options['users'],
                
    'multiple' => true,
                
    'expanded' => true,
                
    'by_reference' => false
            
    ]);

    ....
    }

    /**
         * @param OptionsResolverInterface $resolver
         */
        
    public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            
    $resolver->setDefaults(array(
                
    'users' => []
            ));
        } 
    e poi da controller:

    Codice PHP:

    return $this->createForm(new GroupType(), $entity, [
                
    'action' => $this->generateUrl(....),
                
    'method' => 'POST',
                
    'users' => $company->getUsers()
            ]); 
    dove ovviamente $company->getUsers() torna un arraycollection di entità User


    EDIT: ovviamente la mia prima risposta è sbagliata penso, non è il type "choice" che accetta un array di entità, ma quello "entity" che ti permette di fare l'associazione 1-molti tra entities
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  5. #5
    In merito al fullName (Bundle::nomeEntita) nel repository, è vero solo se fai la chiamata a "from()" del queryBuilder, altrimenti il "$this->createQueryBuilder("unAlias");" ritorna un queryBuilder già tarato sull'entity associata al repository che stai usando
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  6. #6
    Utente di HTML.it L'avatar di Fractals87
    Registrato dal
    Apr 2008
    Messaggi
    1,202
    Eh ma non so perchè non ci riesco.
    Accedendo al metodo findAll del repository di Category, ottengo il mio array di entità.
    Lo passo al metodo add entity, ma mi risponde con questo errore a mio avviso poco comprensibile .
    "A "__toString()" method was not found on the objects of type "Acme\DemoBundle\Entity\Category" passed to the choice field. To read a custom getter instead, set the argument $labelPath to the desired property path. "

    Codice PHP:
    public function createAction(Request $request)
        {
            
    $book = new Book();

        
    //$category = $this->getDoctrine()
        //         ->getRepository('AcmeDemoBundle:Category')
        //         ->findAllReturnArray();
        
    $category $this->getDoctrine()
                 ->
    getRepository('AcmeDemoBundle:Category')
                 ->
    findAll();
        
    //dump($category);exit();
        
    $form $this->createFormBuilder($book)
                         ->
    add('title''text')
                         ->
    add('isbn''text')
                         ->
    add('author''text')
                         ->
    add('description''textarea')
                         ->
    add('price''text')
                 
    /* //Metodo 1 Select con array    
                 /*->add('categoryId', 'choice', array('choices'   => $category,
                                     'required'  => false)
                  )*/

                  //Metodo 2 Select con entity
                 
    ->add('caterogyId''entity', array(
                    
    'class' => 'AcmeDemoBundle:Category',
                    
    'choices' => $category))

                 
    /* // Metodo 3 select tramite query builder
                            ->add('categoryId', 'entity', array('class' => 'AcmeDemoBundle:Category',
                                    'query_builder' => function(EntityRepository $er) {
                                                return $er->createQueryBuilder('cat')
                                                      ->orderBy('cat.id', 'ASC');
                                               },
                ))*/
                         
    ->add('save''submit', array('label' => 'Crea libro'))
                         ->
    getForm();
     
            
    $form->handleRequest($request);
     
            if (
    $form->isValid()) {
                
    //inserisco manualmente l'autore per semplificare l'esempio
                
    $em $this->getDoctrine()->getManager();
                
    //$category = $em->getRepository('AcmeDemoBundle:Category')->find(1);
                //$book->setCategoryId($category);
     
                
    $em->persist($book);
                
    $em->flush();
     
                return 
    $this->redirect($this->generateUrl('_book'));
            } 
    Ultima modifica di Fractals87; 27-04-2015 a 15:15
    Che mestiere difficile.....essere da soli ancora di più

  7. #7
    Utente di HTML.it L'avatar di Fractals87
    Registrato dal
    Apr 2008
    Messaggi
    1,202
    Trovato il fattaccio :
    L'errore che avevo quando tentato di creare un campo entity era dovuto dalla mancanza del metodo
    __toString della classe category.
    Doctrine cerca quel metodo quanto ha la necessità di descrivere la categoria in qualsiasi operazione deve.. E chi cavolo poteva immaginarselo ....


    Altra cosa importate per chi legge...
    La costruzione del campo choise come esposta all'inizio è un errore in quanto dopo il $_POST dei dati avevo un errore a questa riga di codice :

    $form->handleRequest($request);

    Che ad un certo punto andava ad invocare questo metodo dell'oggetto book :

    public function setCategoryId(\Acme\DemoBundle\Entity\Category $categoryId = null)

    Quello che gli veniva passato era descrittivo e non l'entità e quindi andava in errore... il perchè è chiaro anche se non ho capito come mai arrivava un testo e non un oggetto.

    Creando la select option tramite l'oggetto entity invece, symfony ricrea correttamente la categoria e la schiaffa dentro al metodo.
    .
    .
    .
    .
    Symfony sarà pure bello, ma è anche folle.....
    .
    .
    .
    Proseguo alla creazione della classe form per ripulire il Controller, dato che ho già avuto parecchi insulti, neanche avessi ucciso mia mamma.
    Che mestiere difficile.....essere da soli ancora di più

  8. #8
    non serve per forza il __toString, basta specificare l'opzione "property" e dire quale proprietà dell'oggetto (nel tuo caso, l'oggetto Category) deve essere utilizzato per la descrizione (per l'id è la proprietà identificata come ID della entity)

    visto che pensi ad oggetti poi, ovviamente book avraà come getter/setter getCategory/setCategory e non getCategoryId/setCategoryId.

    l'errore che dici che ti dava non l'ho capito sinceramente sul setCategoryId non l'ho capito
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  9. #9
    Utente di HTML.it L'avatar di Fractals87
    Registrato dal
    Apr 2008
    Messaggi
    1,202
    non serve per forza il __toString, basta specificare l'opzione "property" e dire quale proprietà dell'oggetto (nel tuo caso, l'oggetto Category) deve essere utilizzato per la descrizione (per l'id è la proprietà identificata come ID della entity)
    Ok grazie non lo sapevo...

    visto che pensi ad oggetti poi, ovviamente book avraà come getter/setter getCategory/setCategory e non getCategoryId/setCategoryId.
    Si hai ragione, è che ho il vizio mi mettere sempre sto id nel campo del db quando si tratta di una chiave esterna.

    l'errore che dici che ti dava non l'ho capito sinceramente sul setCategoryId non l'ho capito
    Sinceramente non ho capito come mai neanche io.
    Se io creo la select con campo choise symfony ricrea entità dopo il submit dei dati, ma va a richiamare il setter passando il testo.
    Se invece uso il campo entity per creare la select, symfony prima recupera entita e poi la passa al setter.
    Che mestiere difficile.....essere da soli ancora di più

  10. #10
    Se parti da un database "vergine" ti conviene, per velocità e semplicità, ragionare solo ad oggetti della persistenza e lasciare che al database ci pensi l'orm. Ragionare la composizione degli oggetti avendo in testa una visione da "database" piuttosto che ad oggetti, ti porterà più facilmente a complicarti la vita e i model di conseguenza.

    Per il discorso FormType::choice, si vede che quel FormType specifico non ragiona ad entità ma ragiona "plain", ovvero ad esempio ti passa il valore selezionato preso da un'array di valori possibili. Viceversa il tipo "entity" ragiona ad entità/oggetti, permettendoti la scelta multipla o meno, e quindi al setter passerà una entità invece di un valore "primitivo"
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.