我正在构建一个很大程度上依赖于变形关系的包。像往常一样,这种关系需要像以下那样定义关系:
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。据我所知,它可以选择在课堂上调用的所有内容。
现在另一种方法是包含一个特征,让程序员在可发布的文件中填写这些关系,但这感觉不对。
有什么建议吗?
答案 0 :(得分: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中。添加:
|| in_array($key, $this->morphs)
将使该功能按预期工作,从而产生:
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);
}
}