Relazioni ManyToOne o OneToMany doctrine e symfony 3

107 views
Skip to first unread message

Francesco Ingrosso

unread,
Jun 30, 2016, 6:53:24 AM6/30/16
to symfony-it
ho quest'errore : Impossible to access an attribute ("nome") on a integer variable ("1") in admin/admin_composizione_alimento.html.twig at line 19

la parte del controller interessata:

 /**
     * @Route("/admin/composizione/{id}", name="admin_composizione")
    * @Method({"GET"})
     */
   public function adminComposizioneAction($id)
   {   
      $composizione = $this->getDoctrine()->getRepository('AppBundle:Composizione')->findByIdalim($id);
      $elementi = $this->getDoctrine()->getRepository('AppBundle:Elementi')->findAll();
      
      return $this->render('admin/admin_composizione_alimento.html.twig', array('composizione' => $composizione, 'elementi' => $elementi));
      
   }

l'entity:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Composizione
 *
 * @ORM\Table(name="composizione", indexes={@ORM\Index(columns={"idAlimenti"}), @ORM\Index(columns={"idElementi"}), @ORM\Index(name="idx_composizione_idComposizione", columns={"idComposizione"})})
 * @ORM\Entity
 */

class Composizione
{


    /**
     * @var \AppBundle\Entity\Elementi
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Elementi")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="idElem", referencedColumnName="idElementi")
     * })
     */
    private $idelem;


    /**
     * @var \AppBundle\Entity\Alimenti
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Alimenti")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="idAlim", referencedColumnName="idAlimenti")
     * })
     */
    private $idalim;

    /**
     * @var integer
     *
     * @ORM\Column(name="Quantita", type="integer", nullable=false)
     */
    private $quantita;

    /**
     * @var string
     *
     * @ORM\Column(name="Misura", type="string", length=5, nullable=false)
     */
    private $misura;

    /**
     * @var integer
     *
     * @ORM\Column(name="idComposizione", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $idcomposizione;


    /**
     * Set idelem
     *
     * @param integer $idelem
     *
     * @return Composizione
     */
    public function setIdelem($idelem)
    {
        $this->idelem = $idelem;

        return $this;
    }

    /**
     * Get idelem
     *
     * @return integer
     */
    public function getIdelem()
    {
        return $this->idelem;
    }

    /**
     * Set idalim
     *
     * @param integer $idalim
     *
     * @return Composizione
     */
    public function setIdalim($idalim)
    {
        $this->idalim = $idalim;

        return $this;
    }

    /**
     * Get idalim
     *
     * @return integer
     */
    public function getIdalim()
    {
        return $this->idalim;
    }

    /**
     * Set quantita
     *
     * @param integer $quantita
     *
     * @return Composizione
     */
    public function setQuantita($quantita)
    {
        $this->quantita = $quantita;

        return $this;
    }

    /**
     * Get quantita
     *
     * @return integer
     */
    public function getQuantita()
    {
        return $this->quantita;
    }

    /**
     * Set misura
     *
     * @param string $misura
     *
     * @return Composizione
     */
    public function setMisura($misura)
    {
        $this->misura = $misura;

        return $this;
    }

    /**
     * Get misura
     *
     * @return string
     */
    public function getMisura()
    {
        return $this->misura;
    }

    /**
     * Get idcomposizione
     *
     * @return integer
     */
    public function getIdcomposizione()
    {
        return $this->idcomposizione;
    }
}


il template twig (parte interessata):

 {% for c in composizione %}
                  <tr>
                     <td width="80">{{ c.idelem.nome }}</a></td>            <-- qui 
                     <td width="100">{{ c.quantita }}</td>
                     <td width="210">{{c.misura}}</td>
                  </tr>
                  
               {% endfor %}

la tabella sql risultante: 

CREATE TABLE IF NOT EXISTS `composizione` (
`idComposizione` int(11) NOT NULL,
  `idElem` int(11) NOT NULL,
  `idAlim` int(11) NOT NULL,
  `Quantita` int(11) NOT NULL,
  `Misura` varchar(5) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=120 DEFAULT CHARSET=utf8;

mi sa che ho sbagliato qualche relazione? o il richiamo nel twig?


Luca saba

unread,
Jun 30, 2016, 7:10:00 AM6/30/16
to symfo...@googlegroups.com
Non sono sicuro di aver capito benissimo, ma mi sembra che l'esempio che dovresti seguire sia questo:

Se non ho capito male, una composizione contiene un elemento e un alimento. Un alimento può essere in più composizioni e così anche un elemento. Giusto ?

L.

--
Hai ricevuto questo messaggio perché sei iscritto al gruppo "symfony-it" di Google Gruppi.
Visita questo gruppo all'indirizzo https://groups.google.com/group/symfony-it.



--
It is easier to move a problem around (for example, by moving the problem to a different part of the overall network architecture) than it is to solve it.
6th truth - rfc1925
------------------------------------------------------------------
Einstein: Imagination is more important than knowledge. For knowledge is limited, whereas imagination embraces the entire world, stimulating progress, giving birth to evolution.
------------------------------------------------------------------
Heinlein: Specialization is for Insects

Francesco Ingrosso

unread,
Jun 30, 2016, 7:15:26 AM6/30/16
to symfony-it
In pratica... si?... Spiego meglio:

ogni alimento ha la sua composizione fatta da tanti elementi e dalla loro quantità...

visto che non potevo fare una tabella con 137 campi (numero elementi) ho creato una tabella elementi e nella tabella composizione ho messo i suoi id quindi:

ogni alimento ha + composizioni

ogni elemento ha + composizioni


quindi sia alimenti che elementi da ciò che mi hai linkato è una relazione one to many unidirectional??

Francesco Ingrosso

unread,
Jun 30, 2016, 7:35:01 AM6/30/16
to symfony-it
Quindi da ciò che ho capito... la relazione con elementi va fatta nell'entity Alimenti non in Composizione? e forse può avere anche senso.. ma.. mi sa che inizio a confondermi.. in Composizione che relazioni metto? :O

Luca saba

unread,
Jun 30, 2016, 8:09:09 AM6/30/16
to symfo...@googlegroups.com
Ti do lo stesso consiglio che mi diede una volta Massimiliano: pensa agli oggetti.

Doctrine ti permette di separare bene gli oggetti dalla persistenza. Quindi, prima definisci come l'oggetto alimento dovrebbe funzionare, poi aggiungi le annotazioni che l'entity manager utilizzerà per persistere gli oggetti nel DB.

Ciò detto, io la vedrei così:
<?php
/**
 * Alimento
 *
 * @ORM\Table(name="alimento")
 * @ORM\Entity
 */
class Alimento
{
    /**
     * @ORM\OneToMany(targetEntity="Composizione", mappedBy="alimento")
     */
    private $composizioni;
    
    public function __construct() {
        $this->composizioni = new Doctrine\Common\Collections\ArrayCollection();
    }
}

/**
 * Elemento
 *
 * @ORM\Table(name="elemento")
 * @ORM\Entity
 */
class Elemento
{
    /**
     * @ORM\OneToMany(targetEntity="Composizione", mappedBy="elemento")
     */
    private $composizioni;
    
    public function __construct() {
        $this->composizioni = new Doctrine\Common\Collections\ArrayCollection();
    }
    
    private $nome;
}

/**
 * Composizione
 *
 * @ORM\Table(name="composizione")
 * @ORM\Entity
 */
class Composizione
{
    /**
     * @ManyToOne(targetEntity="Alimento", inversedBy="composizioni")
     * @JoinColumn(name="alimento_id", referencedColumnName="id")
     */
    private $alimento;
    /**
     * @ManyToOne(targetEntity="Elemento", inversedBy="composizioni")
     * @JoinColumn(name="elemento_id", referencedColumnName="id")
     */
    private $elemento;
    private $quantita;
}

Chiamando il comando per la generazione delle entità, se tutto va bene, dovrebbe aggiungerti i metodi addElemento() in alimento e addAlimento in elemento.

Quindi, il metodo che ti da l'errore dovrebbe diventare c.elemento.nome

Spero funzioni....

L.

Francesco Ingrosso

unread,
Jun 30, 2016, 8:27:33 AM6/30/16
to symfony-it
Alimento.php

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
    private $misura;


    /**
     * @var integer
     *
     * @ORM\Column(name="idAlimento", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $idalimento;
}


vado a generare le entità e la console mi dà.. [Doctrine\ORM\Mapping\MappingException]                                      
  Class "AppBundle\Entity\Alimento" is not a valid entity or mapped super cla  
  ss.                                                                          

Luca saba

unread,
Jun 30, 2016, 8:56:57 AM6/30/16
to symfo...@googlegroups.com
A me queste in allegato funzionano.
Non ho controllato siano corrette, ma Doctrine mi genera i getter, i setter e gli add senza problemi.

In composizione, non usi @ORM per definire le relazioni....che sia quello ?
Entity.zip

Massimiliano Arione

unread,
Jun 30, 2016, 8:59:19 AM6/30/16
to symfony-it
C'è parecchia confusione. Innanzitutto ogni entity deve avere un nome al singolare.
Poi: la composizione di un alimento è un oggetto che vive di vita propria o piuttosto è una caratteristica dell'alimento? In quest'ultimo caso io eliminerei del tutto l'entity Composizione e metterei direttamente la relazione Alimento -> Elemento con una ManyToMany

ciao
M.

Francesco Ingrosso

unread,
Jun 30, 2016, 9:07:44 AM6/30/16
to symfony-it
In effetti mi sto confondendo ancora di più... Alimento ed Elemento li ho già e non posso sostituirli con quelli nel file zip... al max integrarli xkè alimenti ha tante action etc etc.

In pratica quando clicco sul singolo Alimento mi dovrebbe uscire... Inserisci Composizione se non c'è o mostra Composizione se già esiste... ciò detto cosa mi consigliate di fare? :(

Francesco Ingrosso

unread,
Jun 30, 2016, 11:11:24 AM6/30/16
to symfony-it
Ho integrato un pò i tuoi con quelli che avevo già creato... generato le entità senza problemi ma ho di nuovo lo stesso identico errore :( in allegato trovi i files.. vi prego sono disperato :(
entityetwig.zip

Massimiliano Arione

unread,
Jun 30, 2016, 11:28:59 AM6/30/16
to symfony-it
Il giorno giovedì 30 giugno 2016 17:11:24 UTC+2, Francesco Ingrosso ha scritto:
Ho integrato un pò i tuoi con quelli che avevo già creato... generato le entità senza problemi ma ho di nuovo lo stesso identico errore :( in allegato trovi i files.. vi prego sono disperato :(


Se sei veramente disperato ricomincia da capo seguendo i consigli che ti abbiamo dato.
Se invece, come dici, non puoi cambiare le tue entity perché ci sono "tante action", ti devi tenere il codice che non funziona.
Vedi tu cosa ti conviene

ciao
M.

Luca saba

unread,
Jun 30, 2016, 11:29:43 AM6/30/16
to symfo...@googlegroups.com
C'è molto....disordine.
Innanzitutto, ti ripeto, non confondere l'SQL con gli oggetti. Un campo $idalimento non ha senso in un oggetto. Ha senso nel DB ma non nel tuo codice.

Poi, Alimento ha una relazione ManyToOne con Composizione. E composizione ne ha una ManyToOne con Alimento....una cosa nega l'altra.

Ti suggerirei di riscrivere gli oggetti. E soprattutto di smettere di pensare al DB. Elimina tutti i campi $idalimenti, $idcategorie ecc.

Una volta fatto ordine sugli oggetti, aggiungi le annotazioni che spiegano a Doctrine come interfacciarsi al db. Sarà doctrine a creare gli id nel db e gestire le associazioni tra gli oggetti.

manuel.d...@mashfrog.com

unread,
Jul 1, 2016, 4:52:57 AM7/1/16
to symfony-it
Altro piccolo consiglio nel caso dovresti ripartire da 0, il resto lo hanno già detto tutto gli altri. Visto le diverse associazioni ManyToMany e ManyToOne, un giorno potresti trovarti ad utilizzare le CollectionType nelle tue form. In quel caso Symfony, se hai settato bene i nomi dei metodi, userà i relativi metodi add e remove per gestire tali associazioni tra le entity. In questo caso i nomi delle associazioni/entità sono fondamentali. Ti consiglio quindi di declinare il tuo codice in inglese.

Francesco Ingrosso

unread,
Jul 1, 2016, 8:37:25 AM7/1/16
to symfony-it
Quindi ricapitolando... Parto dalle entity che mi ha inviato Luca Saba... Alimento, Elemento, Composizione, Aggiungo ad Alimento ed Elemento gli altri oggetti di cui ho bisogno e ricompilo il tutto?
Reply all
Reply to author
Forward
0 new messages