2016-01-06 43 views
7

Normalne wykorzystanie polimorficznych związków w Laravel jest dość dobrze opisane w post-User - Image example.Jak zdefiniować relacje podczas korzystania z interfejsów?

Próbuję znaleźć czysty sposób na wdrożenie relacji, powiedzmy, relacji Article/ContentA/ContentB.

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 

Klasy treści niekoniecznie są znane artykułu, więc zdefiniowanie modelu artykułu z wielu MorphedByMany relacji nie jest jak chcę to zrobić.

Być może źle buduję swoje zajęcia. Mógłbym stworzyć klasę ContentEntity, która zmienia się w poszczególne klasy Content, ale chciałbym tego uniknąć, jeśli to możliwe.


Może to lepiej wyjaśnia mój problem.

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'); 
    } 
} 

To działa, ale wydaje się bardzo brudny do mnie. Wydaje mi się, że jest to zbyt duże obciążenie dla programistów, aby móc zarządzać rodzicem o numerze ContentEntity.

Edit: Chyba że ktoś zapewnia lepsze rozwiązanie, poszedłem roztworem stylu EAV wykorzystaniem ContentEntity s.

+0

Proszę napisać kod, "artykuł", "contentA" i "contentB" –

+1

@MohamedKawsara Myślę, że dodana przeze mnie tabela powinna pomóc w wyjaśnieniu mojego pytania. – Sturm

+1

Zgłaszałem to, aby przenieść go do wymiany programistów, ponieważ jest to nieco nietypowy temat dla SO – Sturm

Odpowiedz

0

Można zawsze wyodrębnić relację cecha dla łatwiejszej konserwacji i możliwości rozszerzenia w przyszłości:

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 
} 

Następnie wszystko co musisz zrobić, to użyć cechę w różnych jednostkach :

modele

class Content extends Model { 
    use Contentable; 
} 

class Video extends Model { 
    use Contentable; 
} 

class Article extends Model { 
    use Contentable; 

    protected $contentable = 'many'; 
} 
Powiązane problemy