如何模拟不同的模型来检索多态关系?

Posted

技术标签:

【中文标题】如何模拟不同的模型来检索多态关系?【英文标题】:How can I mock a different model to retrieve a polymorphic relationship? 【发布时间】:2019-10-02 01:46:30 【问题描述】:

我有 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。是否可以在多态关系中模拟另一个模型?

【问题讨论】:

所以您想通过 Reaction 获得 ActivityOpinion 的意见对吗? 如果这是你的目标,看看***.com/questions/43285779/… @AhmedAboud 不完全是我想从从 Opinion 扩展的 ActivityOpinion 获得意见反应。因此,当我从 ActivityOpinion 调用reactions() 时,它将在reactable_type 字段中查询App\Models\Opinion 而不是App\Models\Activity\ActivityOpinion 【参考方案1】:

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

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

Opinion.php

protected $morphClass = 'reaction';

这应该足够了,如果没有,也将它添加到ActivityOpinion模型中。


注意

尝试使用 Eloquent 搜索结果时,这可能会破坏某些内容。检查this other answer 以解决这个可能的不便。



更新

我刚刚发现您可以使用MorphMap 更轻松地完成这一切。来自文档:

自定义多态类型

默认情况下,Laravel 会使用全限定类名来存储 相关模型的类型。例如,给定一对多 上面的示例,其中Comment 可能属于PostVideo, 默认commentable_type 将是App\PostApp\Video, 分别。但是,您可能希望将您的 来自应用程序内部结构的数据库。在这种情况下,你 可以定义一个“变形图”来指示 Eloquent 使用自定义名称 每个模型而不是类名:

use Illuminate\Database\Eloquent\Relations\Relation;

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

您可以在您的boot 函数中注册morphMap AppServiceProvider 或创建一个单独的服务提供商,如果你 希望。

【讨论】:

我已经研究了 morphMap 作为解决方案,但我的理解是你不能将 2 个模型变成一个。 那是因为您正在从另一个扩展一个,但问题是您正试图从另一个模型中的一个中获取结果。也许你应该稍微改变你的表结构以获得你想要的输出(一个字段typemaybe)。

以上是关于如何模拟不同的模型来检索多态关系?的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 中模拟具有关系的模型

检索多态关系 laravel 的所有者

如何最好地链接到 Laravel 中的多态关系

用于模拟两个向量之间的非线性关系的算法

小世界网络模型简介及R模拟

Laravel 5 检索所有多态模型的最佳方法