如何模拟其他模型以检索多态关系?

时间:2019-05-15 00:57:23

标签: php laravel laravel-5 polymorphism

我有3个数据模型,其中一个扩展了另一个模型:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Opinion extends Model
{
    public function reactions()
    {
        return $this->morphMany('App\Models\Reaction', 'reactable');
    }

    ...
}
namespace App\Models\Activity;

use App\Models\Opinion;

class ActivityOpinion extends Opinion
{
    ...
}
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Reaction extends Model
{
    public function reactable()
    {
        return $this->morphTo();
    }

    ...
}

App\Models\Opinion模型与App\Models\Reaction模型具有多态关系。我可以毫无问题地检索所有App\Models\Opinion个反应,因此我知道这种关系很好。

我的问题是,如何从App\Models\Activity\ActivityOpinion模型中检索相同的反应集?因为现在,它正在寻找App\Models\Activity\ActivityOpinion作为关系,但是我需要它来寻找App\Models\Opinion。可以模拟处于多态关系的另一个模型吗?

1 个答案:

答案 0 :(得分:0)

这是因为在存储的数据的多态关系中(如果默认保留),关系类型获取类名称空间(排序)以指定需要返回的模型。这就是为什么当您尝试从reactions()访问ActivityOpinion关系时,它将在App\ActivityOpinion中查找reactable_type值的原因。

您可以自定义变形类以在模型中搜索:

Opinion.php

protected $morphClass = 'reaction';

这应该足够了,如果还不够,也可以将其添加到ActivityOpinion模型中。


注意

当尝试使用Eloquent搜索结果时,这可能会破坏某些东西。选中this other answer,以解决这种可能的不便之处。



更新

我刚刚发现,MorphMap可以使所有操作变得更加容易。从文档中:

  

自定义多态类型

     

默认情况下,Laravel将使用完全限定的类名称进行存储   相关模型的类型。例如,给定一对多   上面的示例中Comment可能属于PostVideo,   默认的commentable_type将是App\Post或   App\Video,。但是,您可能希望解耦   应用程序内部结构中的数据库。那样的话   可以定义一个“变形图”来指示Eloquent使用自定义名称   每个模型而不是类名称:

use Illuminate\Database\Eloquent\Relations\Relation;

Relation::morphMap([
    'posts' => 'App\Post',
    'videos' => 'App\Video',
]);
     

您可以在自己的morphMap功能中注册boot   AppServiceProvider或创建单独的服务提供商(如果您   希望。