从 taggables 加载标签

Load tags from taggables

我想用这段代码显示过去 4 小时内最常用的 4 个标签:

$topTags = Taggable::whereDate('created_at', '>=', now()->subHours(4))
    ->groupBy('tag_id')
    ->orderByRaw('count(tag_id) DESC'))
    ->take(4)
    ->with('tags')
    ->get();

表格

Schema::create('tags', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name')->unique();
            $table->timestamps();
        });

 Schema::create('taggables', function (Blueprint $table) {
            $table->integer('tag_id');
            $table->integer('taggable_id');
            $table->string('taggable_type');
            $table->timestamps();
        });

标签 table 和可标记对象之间需要什么关系?如何访问视图中的标签名称?如果我使用 belongsTo 关系:

class Taggable extends Model
{
    protected $fillable = ['tag_id', 'taggable_id', 'taggable_type'];

    public function tags()
    {
        return $this->belongsTo('App\Tag');
    }
}

标签数组为空:

 #relations: array:1 [▼
        "tags" => null
      ]

最初我建议 Taggable 实体的 tags() 关系名称应该只是 tag()。

那么 Taggable 实体应该有自己的 "id" 像这样:

 Schema::create('taggables', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('tag_id');
            $table->integer('taggable_id');
            $table->string('taggable_type');
            $table->timestamps();
    });

最后,可标记实体应具有如下多态关系:

/**
 * @return \Illuminate\Database\Eloquent\Relations\MorphTo
 */
public function taggable()
{
    return $this->morphTo();
}

public function tag()
{
    return $this->belongsTo('App\Tag');
}

因此您可以像这样访问标签名称:

$topTags = Taggable::whereDate('created_at', '>=', now()->subHours(4))
    ->groupBy('tag_id')
    ->orderByRaw('count(tag_id) DESC'))
    ->take(4)
    ->with('tag')
    ->get();

foreach($topTags as $ttag){
    $ttag->tag->name;
}

不要忘记添加到与 Taggable 相关的其他实体:

/**
 * @return \Illuminate\Database\Eloquent\Relations\morphMany
 */
public function taggables()
{
    return $this->morphMany(Taggable::class, 'taggable');
}

像这样使用 Taggable 关系:

    $anyOtherModel->taggables()->create([
        'tag_id'     => $tag->id,
    ]);