In vista di EAV sembra essere evidente come costruire una relazione tra entity
e attribute
usando la dottrina. Nel caso più complicato ci occupiamo di una relazione Many to Many.
Quindi diciamo che vogliamo mappare un attributo Name
a un'entità User
. Supponendo che un utente abbia esattamente un nome e ogni nome appartenga esattamente a un utente, questo collegamento può essere archiviato usando la relazione One to One
Ma come modellare la relazione tra attribute
e value
? Il problema è che i valori possono essere di diversi tipi o anche bisogno di numeri diversi di campi per salvare le loro informazioni.
Considerare gli attributi name
e phone_number
. Mentre un nome potrebbe essere rappresentato da una stringa, potrebbe essere necessario un numero intero per il numero di telefono. O è anche necessario non solo il numero ma anche il prefisso in un file separato.
Poiché EAV richiede una rappresentazione del valore molto flessibile, non è possibile archiviarli tutti nello stesso campo in una tabella di database (blob di noncuranza, serializzazione dei dati e simili). Pertanto la maggior parte delle implementazioni EAV utilizza tabelle diverse che rappresentano diversi tipi di valore.
Per raggiungere tale flessibilità, dottrina dispone di Inheritance Mapping. In pratica ti permette di estendere le entità della dottrina. In questo modo si specifica un discriminator
per ogni sottotipo di vostra entità:
/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="value_type", type="string")
* @DiscriminatorMap({"name" = "Name", "phone" = "PhoneNumber"})
*/
class Value
{
// ...
}
/** @Entity */
class Name extends Value
{
// ...
}
/** @Entity */
class PhoneNumber extends Value
{
// ...
}
Il Value
classe fornisce un'implementazione comune per tutti i valori, vale a dire un id. Ogni sottoclasse (ad esempio Name
e PhoneNumber
) estende questi valori comuni a quelli specifici, ad esempio campi aggiuntivi.
- Il
@DiscriminatorColumn
definisce una colonna nella relazione parent che memorizza il tipo del valore.
- Il
@DiscriminatorMap
viene utilizzato da doctrine per mappare il tipo da @DiscriminatorColumn
a una di queste classi.
La relazione tra attribute
e value
può essere specificata nella classe padre. Chiamando i valori dall'attributo verranno recuperati tutti i tipi di valori che possono essere filtrati (e gestiti) durante il runtime utilizzando, ad esempio, instanceof.
Fuori dalla scatola, ne dubito. Probabilmente potresti eseguire la tua implementazione. Doctrine è abbastanza estendibile – ZolaKt
Poiché le relazioni delle tabelle in base a un valore (per unire la giusta tabella valore degli attributi in base al tipo di dati) non è possibile (come so), questo dovrebbe essere piuttosto complicato da fare utilizzando Doctrine. –