Le risposte di cui sopra non erano sufficienti per capire cosa stava succedendo, quindi dopo aver approfondito l'argomento penso di avere un modo per spiegarlo che avrà senso per le persone che hanno lottato come ho fatto io per capire.
inversedBy e mappedBy vengono utilizzati dal motore INTERNAL DOCTRINE per ridurre il numero di query SQL che deve eseguire per ottenere le informazioni necessarie. Per essere chiari se non aggiungi inversedBy o mappedBy il tuo codice continuerà a funzionare ma non sarà ottimizzato .
Quindi, ad esempio, guarda le classi seguenti:
class Task
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="task", type="string", length=255)
*/
private $task;
/**
* @var \DateTime
*
* @ORM\Column(name="dueDate", type="datetime")
*/
private $dueDate;
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="tasks", cascade={"persist"})
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
}
class Category
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="Task", mappedBy="category")
*/
protected $tasks;
}
Queste classi se si dovesse eseguire il comando per generare lo schema (ad esempio, bin/console doctrine:schema:update --force --dump-sql
) si noterà che la tabella Categoria non ha una colonna su di essa per le attività. (questo perché non ha un'annotazione di colonna su di esso)
La cosa importante da capire qui è che la variabile task è presente solo in modo che il motore di dottrine interno possa usare il riferimento sopra di esso che dice la sua mappedBy Category. Ora ... non essere confuso qui come lo ero io ... La categoria NON si riferisce AL NOME DELLA CLASSE , si riferisce alla proprietà sulla classe Task chiamata 'protected $ category'.
Come saggio, nella classe Tasks la proprietà $ category menziona che è inversedBy = "tasks", nota che è plurale, NON è IL PLURALE DEL NOME DELLA CLASSE , ma solo perché la proprietà è chiamata 'protected $ tasks' nella Categoria classe.
Una volta capito questo, diventa molto facile capire cosa stanno facendo inversedBy e mappedBy e come usarli in questa situazione.
Il lato che fa riferimento alla chiave esterna come 'attività' nel mio esempio ottiene sempre l'attributo inversedBy perché ha bisogno di sapere quale classe (tramite il comando targetEntity) e quale variabile (inversedBy =) su quella classe per 'lavorare all'indietro' così da parlare e ottenere le informazioni sulla categoria da. Un modo semplice per ricordarlo è che la classe che avrebbe foreignkey_id è quella che deve essere inversedBy.
Dove come con la categoria, e la sua proprietà $ tasks (che non è sulla tabella, ricorda, solo una parte della classe per scopi di ottimizzazione) è MappedBy 'task', questo crea ufficialmente la relazione tra le due entità in modo che la dottrina possa ora tranquillamente utilizzare istruzioni SQL JOIN invece di due istruzioni SELECT separate. Senza mappedBy, il motore di doctrine non saprebbe dall'istruzione JOIN che creerà quale variabile nella classe "Task" inserire le informazioni sulla categoria.
Spero che questo spieghi un po 'meglio.