【问题标题】:Laravel: How to get records from a pivot table?Laravel:如何从数据透视表中获取记录?
【发布时间】:2019-04-25 22:27:56
【问题描述】:

我使用的是 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');
}

用户任务模型

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 吗?我这样做是因为this question

技术负责人告诉我我的代码有误,他会使用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());
}

【问题讨论】:

  • 澄清一下,您是否要获取已分配给用户但今天已完成或根本未完成的任务?
  • @RossWilson 请参考这个问题 (stackoverflow.com/questions/53464283/…) 一个用户可以创建一个任务并分配给多个用户,任务和用户之间是多对多的关系
  • @RossWilson 我想查找由用户创建或分配给用户的所有任务,如果它们未完成或今天已关闭。所以用户可以看到他所有打开的任务+他今天关闭的任务,如果任务是打开的,它们应该按截止日期最差的一个排序,意思是紧迫性
  • 请您为taskstask_user 添加您的迁移(或只是表结构)?
  • @RossWilson 刚刚添加了它们

标签: php laravel eloquent lumen


【解决方案1】:

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

注意

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();

【讨论】:

    【解决方案2】:

    以下博客文章介绍了一对多任务分配示例。

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

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

    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();
    

    【讨论】:

    • 那么,要从用户那里获取任务ID,它就变成task.user.id?
    • 我明白了,我再次查看了你发布的内容,我已经用我认为我能理解你想要的内容更新了我的答案..
    • 您的第二个答案正是我想要的,先生,唯一的是它为所有用户获取所有任务,我只想为授权用户获取所有任务。
    • 所以你的意思是关闭查询的日期? Auth:user()->tasks()->where('is_done',1)->orWhere('closed_dated', Carbon::today()) ?您必须修改它以将 OR 分组以包含 domain_id
    • 我添加了一个结论,我认为这是可能的,但我以前从未编写过这样的嵌套查询..
    猜你喜欢
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    相关资源
    最近更新 更多