2017-01-07 5 views
5

Laravelとモデル継承に関係するこの狂った考えがあります。私は単一の親を持つモデルのセットを構成したいと思いますが、子モデルを要求するときにデータを返すことを望みます。たとえば、私は親である連絡先モデルを持っています:Laravel 5モデル継承 - 子モードを取得するときに親データを返す

Contacts: id, first_name, last_name, image

次に、連絡先から継承する一連の連絡先タイプがあります。これらの子モデルのそれぞれは、独自のフィールドセットを持っています(つまり、参加したときに知る必要があるメンバーですが、ボランティアにとって最新の救急証明書があるかどうかを知る必要があるかもしれません)。ここではいくつかの例は以下のとおりです。

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

とすべてがこのように、1行だったかのようにデータが返された連絡先とメンバーを持っている:

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

私のような何かを行うことができるのが大好きだ


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

もう少し難しくするために、親に適用されるすべての関係を子供のために働かせたいと思います。メンバーのモデルは、親がその関係を持っているので、それが連絡先に関連した携帯電話を返すPhoneモデルに定義された関係を持っていないにもかかわらず、

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

そして:だから私はこのような何かを行うことができます。

私はまた、Laravelはエラーをスローしたデータを取得するとき、子供に属していないいない列を指定できるようにしたいと思います:

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

私は雄弁モデルをオーバーライドして周り混乱していると私自身のバージョンのすべてを書いて動作しているメソッドを見つけましたが、これを動作させるためにはすべてのメソッドをオーバーライドしなければならないかもしれないように見えます。それは単なるEloquentや他の別注)ソリューションです。

質問:私はLaravelでこれを行う "簡単な"方法があるのか​​、それとも決して意図しないことをするようにしようとしていますか?

答えて

0

は、私はあなたがこのように行うことができると思う:あなたのメンバーのモデルが接触モデルにbelongsToの関係を定義している必要があります。もちろん、

$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を拡張する各クラスでこれらのオーバーライドを追加します)。

(私はそれを徹底的にテストしていません。試してみてください。また、これは熱心な負荷を直接処理することもありません。それをサポートしたい場合は、上書きする対象を見つけてください)

関連する問題