【问题标题】:How to count amount of data based on attributes in pivot table?如何根据数据透视表中的属性计算数据量?
【发布时间】:2026-01-25 06:35:01
【问题描述】:

我是 Laravel 5 的初学者,我正在尝试开发一个博客,假设我有一个与标签模型有多对多关系的文章模型。

这是文章模型:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Article extends Model {

    protected $fillable = [
        'name',
        'description'
    ];

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

}

这是标签模型:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model {

    public function articles() {
        return $this->belongsToMany('App\Article')->withTimestamps();
    }

}

这里是 Articles 表和 Article_Tag 数据透视表的迁移:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateArticlesTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('name')->unique();
            $table->text('description');
            $table->timestamps();
        });

        Schema::create('article_tag', function(Blueprint $table)
        {
            $table->integer('article_id')->unsigned()->index();
            $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');

            $table->integer('tag_id')->unsigned()->index();
            $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');

            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('article_tag');
        Schema::drop('articles');
    }

}

这是标签表的迁移:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTagsTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tags', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('name')->unique();
            $table->integer('count')->unsigned();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tags');
    }

}

假设我的数据库中有 3 个标签,“生活方式”、“社交”、“经济”。

假设一篇文章是用标签“lifestyle”创建的,那么在 ArticleController 中,在 store 函数中,我希望将“lifestyle”标签上的 count 属性设置为数据库中文章的数量(在在这种情况下,它将使用 count() 函数从具有“生活方式”标签的数据透视表中计数。

如果 tag_id 在文章表中,我可以在控制器中这样做:

$article = new Article($request->all());
$article->save();

foreach($article->tags as $tag) {
    $tag->count = Article::where('tag_id', $request->tag_id)->count();
    $tag->save();
}

但在这种情况下,where 函数依赖于数据透视表中的一列,我不知道该怎么做。

我的初学者的错误有什么解决方案吗?提前致谢。

【问题讨论】:

    标签: php laravel count laravel-5 eloquent


    【解决方案1】:

    您可以通过调用轻松统计属于给定标签的文章:

    $tag->count = $tag->articles()->count();
    $tag->save();
    

    上面将运行 2 个 SQL 查询 - 一个用于计数,一个用于更新标签。您还可以尝试以下方法,这将执行单个查询:

    Tag::whereId($tag->id)->increment('count');
    

    这将运行单个 SQL UPDATE 查询:

    UPDATE `tags` SET `count` = `count` + 1 WHERE `id` = {$tag->id}
    

    【讨论】:

    • 哇,它确实有效。从来没想过这么简单。谢谢伙计,你让我开心。 :D