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

标签 mysql laravel laravel-5 polymorphism

有时我们会使用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';
}

这很好,因为现在您可以直接对 Status 或 Source 作为字符串而不是 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')

如您所见,问题出在 taggablestaggable_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,这有点乱。

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

最佳答案

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

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

理论上,您应该需要在 morph 映射中列出 Posts 模型/表,因为系统会根据命名自动为其生成“posts”类型。

关于mysql - Laravel 5 具有多态关系的只读 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47399135/

相关文章:

php - 如何每天更新一次缓存(00 :00:00) in Laravel 5?

mysql - 更新MYSQL中的重复行以进行逻辑删除

php - 使用不带时间的 DATETIME 的 MYSQL SELECT 语句

php - 使用 PHP 数组中的 optgroup 生成下拉菜单

Laravel:如何使用 Artisan Facade 在 Controller 和模型中调用终端命令

php - 将YouTube视频上传到AWS S3不能正常播放

mysql - 如何在 Laravel 5.4 中进行左连接

mysql - 在 Laravel 查询中选择行

java - spring boot data jpa mysql无法创建数据库

java - JPA/eclipse-link 2.6.0/mysql : incorrect generated table name