Laravel 5 具有多态关系的只读视图模型

Posted

技术标签:

【中文标题】Laravel 5 具有多态关系的只读视图模型【英文标题】:Laravel 5 Read Only View Model with polymorphic Relationship 【发布时间】:2017-11-20 18:53:08 【问题描述】:

有时我们使用 mysql Views 来组织相关的表,以便于搜索和排序。例如,如果您有带有状态和来源的帖子。

Post
    subject
    body
    source_id
    status_id

Status
    id
    label
    other_field

Source
    id
    label
    other_field


View
   create view read_only_posts as
   SELECT statuses.label as status, sources.label as source, posts.*
   from posts
   left join statuses on statuses.id = posts.status_id
   left join sources on sources.id = posts.source_id

然后我们有 Post 模型和一个额外的模型:

// Post.php
class Post extends Model

    //


// ReadOnlyPost.php
class ReadOnlyPost extends Post

    protected $table = 'read_only_posts';

这很好,因为现在您可以直接将状态或源作为字符串而不是 id 进行排序或过滤。您还可以包含“other_field”。

但我们有一个问题需要帮助。如果您在 Posts 上有一个多态的多对多关系,我无法让它在只读版本上工作。例如,如果您有多态标签:

// Post.php Model
public function tags()

    return $this->morphToMany(Tag::class, 'taggable');

问题是当你过滤带有特定标签的帖子(使用只读模型)时,你会得到这样的 sql:

从存在的read_only_posts 中选择计数(*)作为聚合(从tags 内部连接taggables 中选择* tags.id = taggables.taggable_id 其中read_only_posts.@ 987654333@ = taggables.taggable_typetaggables.taggable_type = 'read_only_posts' 和 label = '测试')

如您所见,问题在于 taggables.taggable_type = 'read_only_posts'

我找不到覆盖模型的变形类型的方法。 (我在 laravel 5.4 上,MorphClass 不再存在了)。变形图是一个关联数组,所以你不能这样做:

// AppServiceProvider
public function boot()

    Relation::morphMap([
        'posts' => Post::class,
        'posts' => ReadOnlyPost::class, <--- Can't do this

我的愚蠢解决方法是,当我将标签附加到帖子时,我还将它附加到 ready_only_posts,这有点混乱。

还有其他人将视图用于只读模型吗?任何人都有更好的方法来覆盖特定模型的多对多多态类型?

【问题讨论】:

【参考方案1】:

查看代码,我相信这可能有效。

class ReadOnlyPost extends Posts

    public function getMorphClass() 
         return 'posts';
    

理论上你应该需要在变形图中列出Posts模型/表,因为系统会根据命名自动为其生成“帖子”的类型。

【讨论】:

不幸的是,这在 5.4 中消失了。 laravel.com/api/5.4/search.html?search=MorphClass @Patrick_Finucane 好的,我查看了代码,我相信上面的方法可能有效。不过目前还没有项目设置来测试它 很遗憾,您不能在 morphMap 中同时映射两者。请参阅我的问题的底部。 好的。我的阅读能力很糟糕。对不起。 'getMorphClass' 的覆盖是否有效?另外,你需要在变形图中提到 Post 类吗?默认是“帖子”对吧?

以上是关于Laravel 5 具有多态关系的只读视图模型的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5中的反向多态关系

Laravel:Eloquent模型中的多重多态关系

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

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

Laravel 5.8多态关系`nullableMorphs`不起作用

Laravel/Eloquent - 创建与可能具有或不具有属性的父模型相关的多个子模型的关系