问题的标题可能看起来很奇怪,但我将简要解释一下。我还没有遇到任何问题,但是正在考虑有关以下方法的任何建议。
我有下表:
articles
hasMany(tags)
movies
hasMany(tags)
series
hasMany(tags)
subs (morph)
media_id
media_type
user_id
前三个表都具有many
标记,其中subs
表之间具有Morph
关系。
这个概念很简单,用户可以订阅movies
和/或series
而不能订阅articles
,也就是说,选择接受movies
中的记录。
将插入以下记录:
media_id => 1, media_type => movie, user_id => 1
假设我们在subs
表中有1万条这样的记录。现在,我在articles
中创建带有特定标签的记录。我想通知subs
中所有已选择movies
和/或series
的用户,这些用户的标签与我从articles
定位的记录完全相同
TL; DR:通知对电影或电视剧中的特定标签感兴趣的用户。
为此,我在morphTo
模型中添加了subs
:
public function media(){
return $this->morphTo();
}
逻辑很简单:
tags()
关系并将其保存到变量中。subs
。morphTo
关系并获取其标签。比较并继续。
$article = MediaArticle::find($notificationable_id);
$article_tags = $article->tags;
$subbed_users = array();
if (empty($article_tags) === false) {
$subs = NotificationMediaSub::all();
foreach ($subs as $sub) {
$sub_tags = $sub->media->tags;
foreach ($sub_tags as $sub_tag) {
foreach ($article_tags as $article_tag_title) {
if (strcasecmp($sub_tag->title, $article_tag_title->title) === 0) {
array_push($subbed_users, $sub->user_id);
}
}
}
}
// continue here
}
我发现这种方法确实很费力,并且可能导致服务器速度大大降低。有没有更好的方法可以实现我的目标?
=======================
我在其中将media_tags_relationship
定义为模型:
public function media() {
if ($this->taggable_type === AdminHelper::MORPH_MEDIA_TRANSLATION_MOVIE['original']) {
return $this->belongsTo(MediaMovie::class, 'taggable_id', 'id');
} elseif ($this->taggable_type === AdminHelper::MORPH_MEDIA_TRANSLATION_SERIES['original']) {
return $this->belongsTo(MediaSeries::class, 'taggable_id', 'id');
}
return $this->belongsTo(MediaMovie::class, 'taggable_id', 'id')->where('id', 0);
}
现在,我正在像这样获取潜艇:
$article = MediaArticle::find($notificationable_id);
$article_tags = $article->tags;
$subbed_users_tokens = array();
if (empty($article_tags) === false) {
$article_tags = $article_tags->map(function ($tag) {
return $tag->title;
});
$related_tags = MediaTag::whereIn("title", $article_tags)->get();
$related_tags = $related_tags->map(function ($tag) {
return $tag->id;
});
$tags_relationship = MediaTagsRelationship::whereIn("tag_id", $related_tags)->where("taggable_type", "movie")->orWhere("taggable_type", "series")->get();
foreach ($tags_relationship as $tag_relationship) {
$media = $tag_relationship->media()->with('subs')->get();
if (empty($media) === false) {
$media = $media[0];
$subs = $media->subs->map(function ($sub) {
return $sub->firebase_token;
});
array_push($subbed_users_tokens, $subs);
}
}
}