Laravel: 如何从数据透视表 table 获取记录?

Laravel: How to get records from a pivot table?

我正在使用 Lumen 5.1,任务和用户之间存在多对多关系

任务模型

public function user()
{
    return $this->belongsToMany('App\Models\Auth\User', 'task_user');
}

public function domain()
{
    return $this->hasOne('App\Models\Domain', 'domain_id');
}

用户模型

public function tasks()
{
    return $this->belongsToMany(Task::class, 'task_user');
}

UserTask 模型

class UserTask {}

我要搜索获取任务的用户,我的代码是

$tasks = Task::Where(function ($query) use ($domainId) {
    $query->where("domain_id", $domainId)
        ->where("is_done", 0)
        ->orwherehas('tasks.user.id', \Auth::id)
        ->orderBy('due_date', 'DESC');
})
->orWhere(function ($query) use ($domainId) {
    $query->where("domain_id", $domainId)
        ->Where("is_done", 1)
        ->Where("closed_dated", Carbon::today())
        ->orwherehas('tasks.user.id', \Auth::id)
        ->orderBy('closed_date', 'ASC');
})
->get();

我的问题 whereHas 正确吗? tasks.user.id 正确吗?我可以通过这种方式获取用户 ID 吗?我这样做是因为

技术负责人告诉我,我的代码是错误的,他会让你使用where,他说whereHas当你想要运行一个闭包时。

迁移:

任务

public function up()
{
    Schema::create($this->getTable(), function (Blueprint $table) {
        $table->increments('id');
        $table->string('title')->nullable();
        $table->dateTime('submit_date');
        $table->dateTime('closed_date');
        $table->dateTime('due_date');
        $table->tinyInteger('is_done')->default(0);

        $table->integer('domain_id')->unsigned()->nullable();
        $table->foreign('domain_id')->references('id')
            ->on(self::getTableName('domains'))->onDelete('cascade');

        $table->bigInteger('created_by')->unsigned()->nullable();
        $table->foreign('created_by')->references('id')
            ->on(self::getTableName('auth_users', false))->onDelete('cascade');

        $table->bigInteger('closed_by')->unsigned()->nullable();
        $table->foreign('closed_by')->references('id')
            ->on(self::getTableName('auth_users', false))->onDelete('cascade');
        $table->timestamps();
    });

}

public function down()
{
    Schema::drop($this->getTable());
}

task_user

public function up()
{
    Schema::create($this->getTable(), function (Blueprint $table) {
        $table->increments('id');
        $table->integer('task_id')->unsigned()->nullable();
        $table->foreign('task_id')->references('id')
            ->on(self::getTableName('tasks'))
            ->onDelete('cascade');

        $table->bigInteger('user_id')->unsigned()->nullable();
        $table->foreign('user_id')->references('id')
            ->on(self::getTableName('auth_users', false))
            ->onDelete('cascade');
    });

}

public function down()
{
    Schema::drop($this->getTable());
}

下面的博客post介绍了一个一对多的任务分配示例。

https://medium.com/@brice_hartmann/building-a-user-based-task-list-application-in-laravel-eff4a07e2688

为当前用户获取任务,belongsToMany 与用户模型的关系为:

Auth::user()->tasks()->where('is_done',0) .... ->get();

获取用户任务:

Tasks::with(['user'])->where('is_done',1) ... ->get();

授权用户结论...我不是 100% 确定这是正确的:

Auth::user()->tasks()
    ->where('domain_id', $domainId)
    ->where(function ($query) {
        $query->where('is_done', 1)
              ->orWhere(function($query) {
                 $query->where('is_done', 0)
                       ->where('closed_dated', Carbon::today())
            });
        });
    })
    ->get();

不,whereHas 对这里的两者都不正确。此外,您不会在 Task 模型上说 whereHas('tasks...')

NB

whereHas 的第二个参数应该是一个闭包(函数),Auth::id 应该是 Auth::id()。如果你愿意,你也可以使用 auth() 辅助函数而不是 Auth 门面。

以下应该能满足您的需求:

$tasks = Task::where("domain_id", $domainId)
    ->where(function ($query) use ($domainId) {
        $query
            ->where("is_done", 0)

            //whereHas - 1st arg = name of the relationship on the model, 2nd arg = closure
            ->whereHas('user', function ($query) {
                $query->where('id', auth()->id());
            });
    })
    ->orWhere(function ($query) use ($domainId) {
        $query
            //If "is_done" = 1 only when it's been closed then you won't need to check "is_done"
            ->where("is_done", 1)
            ->where('closed_by', auth()->id())
            ->whereDate("closed_dated", '>=', Carbon::today()->startOfDay());
    })
    ->orderBy('due_date', 'DESC')
    ->orderBy('closed_date', 'ASC')
    ->get();