2016-11-21 106 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) 

会使功能按预期方式工作,并且因此导致