2016-01-06 16 views
7

L'utilizzo normale delle relazioni polimorfiche in Laravel è trattato piuttosto bene dall'esempio Post-User-Image.Come definire le relazioni quando si utilizzano le interfacce

Sto cercando di trovare un modo pulito per implementare le relazioni, diciamo una relazione Articolo/ContenutoA/ContenutoB.

articles 
    id 

content_1 
    id 

content_2 
    id 

user_defined_content_n 
    id 

contentables 
    article_id 
    contentable_id 
    contentable_type // content_2, user_defined_content_n 

Le classi di contenuti non sono necessariamente conosciuti dal articolo, in modo da definire il modello articolo con molti MorphedByMany rapporti non è come io voglio fare questo.

Forse sto strutturando male le mie classi. Potrei creare una classe ContentEntity che si trasforma in singole classi Content ma vorrei evitarlo se possibile.


Forse questo spiega meglio il mio problema.

class Article extends Model { 
    public function contentEntities() { 
     return $this->hasMany(ContentEntity::class); 
    } 
} 

class ContentEntity extends Model { 
    public function contentable() { 
     return $this->morphTo(); 
    } 
} 

class Content extends Model { 
    public function contentEntity() { 
     return $this->morphOne(ContentEntity::class, 'contentable'); 
    } 
} 

class Video extends Model { 
    public function contentEntity() { 
     $this->morphOne(ContentEntity::class, 'contentable'); 
    } 
} 

Questo funziona ma sembra molto impuro per me. Penso che aggiunga troppi costi di sviluppo per dover gestire il genitore ContentEntity.

Edit: A meno che qualcuno fornisce una soluzione migliore, sono andato con una soluzione stile EAV utilizzando ContentEntity s.

+0

Si prega di inviare un po 'di codice, il tuo 'articolo',' contenutoA' e 'contenutoB' –

+1

@MohamedKawsara Penso che la tabella che ho aggiunto dovrebbe aiutare a chiarire la mia domanda. – Sturm

+1

L'ho segnalato per averlo spostato nello scambio di programmatori poiché è un po 'fuori tema per SO – Sturm

risposta

0

Si può sempre estrarre la relazione ad un tratto per una più facile manutenzione e estendibilità in futuro:

Trait

trait Contentable 
{ 
    public function contentEntity() { 
     if(property_exists($this, 'contentable') && $contentable == 'many') { 
      return $this->hasMany(ContentEntity::class); 
     } else { 
      return $this->morphOne(ContentEntity::class, 'contentable'); 
     } 
    } 

    // Future implementations 
} 

Poi tutto quello che dovete fare è utilizzare il tratto in varie entità :

modelle

class Content extends Model { 
    use Contentable; 
} 

class Video extends Model { 
    use Contentable; 
} 

class Article extends Model { 
    use Contentable; 

    protected $contentable = 'many'; 
} 
Problemi correlati