2016-11-21 51 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

原來,這是一個兩步驟的答案。您需要修復急切的加載和一個用於延遲加載。

eager loader需要在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) 

會使功能按預期方式工作,並且因此導致