2017-01-07 55 views
5

Więc mam ten szalony pomysł, że ma do czynienia z laravel i modelu dziedziczenia. Chciałbym skonfigurować zestaw modeli z pojedynczym rodzicem, ale gdy zażądam modelu podrzędnego, chciałbym zwrócić dane. Na przykład chciałbym mieć model Kontakty, który jest rodzicem:laravel 5 model dziedziczenia - zwracania danych nadrzędnego, gdy coraz tryb dziecko

Contacts: id, first_name, last_name, image

Wtedy miałbym serię typów kontaktów, które dziedziczą po Kontaktach. Każdy z tych modeli potomnych miałby własny zestaw pól (tj. Dla członków, których muszę znać, kiedy dołączyli, itp., Ale dla wolontariuszy może potrzebować wiedzieć, czy mają aktualny certyfikat pierwszej pomocy). Oto kilka przykładów:

Members: contact_id, joined_on, birthday, medical_concerns 
Volunteers: contact_id, current_first_aid, interests 
Staff: contact_id, pay_rate 

chciałbym być w stanie zrobić coś takiego:

$members = \App\Member::all();

i mieć dane kontaktowe i członek wrócił jak gdyby wszystko było w jednym rzędzie, tak:


+---+------------+-----------+-------+------------+------------+------------------+ 
|id | first_name | last_name | image | joined_on | birthday | medical_concerns | 
+---+------------+-----------+-------+------------+------------+------------------+ 
| 1 | Fred  | Bloggs | null | 2015-01-01 | 1993-10-22 | false   | 
| 2 | Jim  | Phillips | null | 2016-04-30 | 1987-09-22 | true    | 
+---+------------+-----------+-------+------------+------------+------------------+ 

I aby było to trochę trudniejsze, chciałbym, aby wszystkie relacje, które mają zastosowanie do rodzica, były przydatne dla dziecka. Tak mógłby zrobić coś takiego:

$members = \App\Member::find(1)->phone

I choć model Użytkownik nie posiada zdefiniowanej relacji do modelu telefonu byłoby powrócić telefon związanej z kontaktem bo rodzic ma ten związek.

Chciałbym również, aby móc określić kolumny, które nie należą do dziecka podczas pobierania danych i nie mają laravel rzucać błąd:

$members = \App\Member::all(['first_name','last_name','joined_on']) 

mam zawiedli wokół z nadrzędnymi modelu i wymowny pisząc własną wersję wszystkich i znajduję metody, które działają, ale wygląda na to, że będę musiał zastąpić wszystkie metody, aby to zadziałało i być może byłoby to więcej pracy niż tylko wymyślanie Wymyślnych i szukanie innych (lub moich własnych na zamówienie).

Więc myślę, że moje pytania to: Czy istnieje „łatwy” sposób to zrobić z laravel albo ja staramy się to robić rzeczy, które nigdy nie był przeznaczony do zrobienia?

Odpowiedz

0

myślę, że można zrobić tak:

$members = \App\Members::with('contact')->all(); 

Oczywiście model Członkowie powinni mieć zdefiniowane relacje belongsTo do modelu kontaktowego.

0

Is there an "easy" way to do this with Laravel or am I trying to make it do things that it was never intended to do?

Tak.

Eloquent doen't zarządzać dziedziczenia w ten sposób. Zamiast tego lepiej jest zaimplementować polymorphic relations.

Jednak nadrzędnym tylko ten kawałek wydaje się służyć celom:

abstract class ContactSubclass extends Contact 
{ 
    protected $with = 'parent'; 

    public function parent() 
    { 
     return $this->belongsTo(Contact::class, 'contact_id'); 
    } 

    public function newQuery() 
    { 
     $contactTable = (new Contact())->getTable(); 
     $thisTable = (new static())->getTable(); 

     $builder = parent::newQuery(); 
     $builder->join($contactTable, "$thisTable.contact_id", '=', "$contactTable.id"); 

     return $builder; 
    } 

    public function newFromBuilder($attributes = [], $connection = null) 
    { 
     $model = parent::newFromBuilder($attributes, $connection); 

     if ($model->parent) { 
      $model->setRawAttributes(array_merge($model->parent->getAttributes(), $model->getAttributes()), true); 
     } 

     return $model; 
    } 

    protected function getRelationshipFromMethod($method) 
    { 
     if (method_exists(parent::class, $method)) { 
      return $this->parent->getRelationshipFromMethod($method); 
     } 

     return parent::getRelationshipFromMethod($method); 
    } 
} 

Czy Member i inne podklasy rozszerzyć tę klasę (lub dodać te przesłonięcia w każdej klasie, która rozciąga Contact).

(nie testowałem go dokładnie, spróbować.Co więcej, nie poradzi sobie bezpośrednio z dużymi obciążeniami; spróbuj znaleźć, co zastąpić, jeśli chcesz to wspierać.)