2016-11-21 4 views
2

モーフィングの多くの関係に大きく依存するパッケージを作成しています。いつものようにこのような関係を定義する必要があります:Laravel 5ダイナミックモーフィングメソッド

public function foos() 
{ 
    return $this->morphToMany('App\Models\Foo', 'barable'); 
} 

これは明らかにうまく動作し、問題はありません。

これらの関係の多くは定義する必要があります。そして、私はそれらをループし、パッケージを簡単に構成できるように自動的に構築したいと思います。

私は次のことを試してみました:

public function __get($name) 
{ 
    if($name == 'foos') { 
     return $this->morphToMany('App\Models\Foo', 'barable'); 
    } 
} 

これは、データを取得するクエリを開始しません。呼び出されますが、データは返されません。

__call関数は私にとっても論理的だったようですが、Laravelを壊すだけです。私が言うことができる限り、それはクラスで呼び出されているすべてを拾う。

もう1つの方法は、特性を含めることで、プログラマがこれらの関係をパブリッシュ可能ファイルに記入することですが、それは間違っていると感じます。

提案がありますか?

答えて

1

2段階の回答です。熱心な読み込みのための修正と、遅延読み込みのための修正が必要です。

eagerローダーは、model.phpで指定された__call()関数を受け取り、ステートメントが失敗した場合にリダイレクトします。

public function __call($method, $arguments){ 
    if(in_array($method, ['bars'])) { 
     return $this->morphToMany('App\Bar', 'barable'); 
    } 
    return parent::__call($method, $arguments); 
} 

遅延ローダーは、メソッドが存在するかどうかを確認しますが、明らかにそうではありません。あなたのモデルにそれを追加し、 "OR"ステートメントを追加すると、それらの作業もできます。元の関数はmodel.phpにもあります。

public function getRelationValue($key) 
{ 
    // If the key already exists in the relationships array, it just means the 
    // relationship has already been loaded, so we'll just return it out of 
    // here because there is no need to query within the relations twice. 
    if ($this->relationLoaded($key)) { 
     return $this->relations[$key]; 
    } 

    // If the "attribute" exists as a method on the model, we will just assume 
    // it is a relationship and will load and return results from the query 
    // and hydrate the relationship's value on the "relationships" array. 
    if (method_exists($this, $key) || in_array($key, $this->morphs)) { 
     return $this->getRelationshipFromMethod($key); 
    } 
} 
:追加:で期待通りに

|| in_array($key, $this->morphs) 

が関数作業を行いますので、結果