数据库
首页 > 数据库> > mysql-具有多态关系的Laravel 5只读视图模型

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

作者:互联网

有时,我们使用MySql视图来组织相关表,以使其更易于搜索和排序.例如,如果您有带有状态和来源的帖子.

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:

select count(*) as aggregate from read_only_posts where exists (select * from tags inner join taggables on tags.id = taggables.taggable_id where read_only_posts.id = taggables.taggable_type and taggables.taggable_type = ‘read_only_posts’ and label = ‘test’)

如您所见,问题是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,这有点混乱.

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

解决方法:

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

class ReadOnlyPost extends Posts
{
    public function getMorphClass() {
         return 'posts';
    }
}

从理论上讲,您应该需要在morph映射中列出Posts模型/表,因为系统将基于命名自动为其生成“ posts”类型.

标签:laravel,laravel-5,polymorphism,mysql
来源: https://codeday.me/bug/20191110/2014836.html