2017-01-07 33 views
5

所以我有這個與Laravel和模型繼承有關的瘋狂想法。我想用一個父級配置一組模型,但是當我請求子模型時,我希望返回數據。例如,我將有一個聯繫人模型,它是父級:Laravel 5模型繼承 - 獲取子模式時返回父數據

Contacts: id, first_name, last_name, image

然後,我將有一系列從聯繫人繼承的聯繫人類型。這些兒童模型中的每一個都有自己的一套領域(即對於我加入時需要知道的成員等,但對於我可能需要知道他們是否擁有最新急救證書的志願者)。下面是幾個例子:

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

我希望能夠做一些事情,如:

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

,並有接觸和成員返回的數據,就好像一切都是一個行,像這樣:


+---+------------+-----------+-------+------------+------------+------------------+ 
|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    | 
+---+------------+-----------+-------+------------+------------+------------------+ 

爲了讓它更難一些,我希望適用於家長的所有關係都適合孩子。所以,我可以做這樣的事情:

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

而且,即使會員模型沒有定義手機型號,它將返回相關聯繫人的電話,因爲家長有關係的關係。

我也想能夠指定檢索數據時不屬於子列,而不是有Laravel引發錯誤:

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

我已經與重寫雄辯模型周圍混亂和寫我自己的版本的全部和找到正在工作的方法,但它看起來像我可能不得不重寫所有的方法來使這個工作,也許這將是更多的工作,而不是放棄雄辯和尋找其他(或我自己的定製)解決方案。

所以我想我的問題是:是否有一個「簡單」的方式來做到這一點與Laravel或我想讓它做它從來沒有打算做的事情?

回答

0

我認爲你可以這樣做:

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

當然你的會員模式應該已經定義了屬於關聯關係的接觸模型。

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?

是的。

雄辯不能用這種方式來管理遺傳。相反,實施polymorphic relations可能會更好。

然而,僅僅覆蓋該位似乎成爲你的目的:

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

Member和其他子類繼承這個類(或每一個擴展Contact類添加這些覆蓋)。

(我還沒有徹底測試過,試試看。而且,這不會直接處理急切的負載;如果你想支持的話,請嘗試找到要重寫的內容。)