有时我们会使用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 * fromtags
inner jointaggables
ontags
.id
=taggables
.taggable_id
whereread_only_posts
.id
=taggables
.taggable_type
andtaggables
.taggable_type
= 'read_only_posts' andlabel
= '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,这有点乱。
还有其他人将 View 用于只读模型吗?谁有更好的方法来覆盖特定模型的多对多多态类型?
最佳答案
查看代码,我相信这可能有效。
class ReadOnlyPost extends Posts
{
public function getMorphClass() {
return 'posts';
}
}
理论上,您应该需要在 morph 映射中列出 Posts
模型/表,因为系统会根据命名自动为其生成“posts”类型。
关于mysql - Laravel 5 具有多态关系的只读 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47399135/