【问题标题】:Thread not returning all subscribed users线程未返回所有订阅用户
【发布时间】:2019-12-15 14:54:42
【问题描述】:

关于

我将 Laravel 5.8 与 MySQL 一起使用。我有一个线程表和线程详细信息表。我正在从线程中获取所有记录,并且它与 threaddetails 表相关联,只要在 threaddetails 中找到匹配的 user_id。

预期

它应该返回我的所有线程和线程中存在的订阅用户。

当前

它返回我所有的线程,但从 threaddetails 表中它只返回我的记录。它不会返回与我聊天的其他订阅用户。

问题:

我是否在 Query to fetch the data 部分遗漏了任何内容?

表:线程 - 架构

Schema::create('tblthread', function (Blueprint $table) {
    $table->unsignedMediumInteger('thread_id')->autoIncrement();
    $table->timestamp('created_on');
});

表线程示例数据

INSERT INTO tblthread (thread_id, created_on) VALUES
(1, '2019-08-07 20:30:54');

表线程详细信息

Schema::create('tblthreaddetails', function (Blueprint $table) {
    $table->unsignedMediumInteger('thread_detail_id')->autoIncrement();
    $table->unsignedMediumInteger('thread_id');
    $table->unsignedMediumInteger('user_id')->nullable();

    $table->foreign('thread_id')->references('thread_id')->on('tblthread')->onDelete('cascade');
});

示例数据 - 线程详细信息

INSERT INTO `tblthreaddetails` (`thread_detail_id`, `thread_id`, `user_id`) VALUES
(1, 1, 1),
(2, 1, 6);

查询以获取数据

ThreadModel::with(["Details" => function($query) use ($user_id) {
    $query->where("user_id", $user_id);
}])->get();

线程模型

class ThreadModel extends Model
{
    public $table = 'tblthread';
    public $primaryKey = 'thread_id';
    public $timestamps = false;

    public function Details() {
        return $this->hasMany("\ThreadDetailsModel", "thread_id", "thread_id");
    }
}

线程细节模型

class ThreadDetailsModel extends Model
{
    public $table = 'tblthreaddetails';
    public $primaryKey = 'thread_detail_id';
    public $timestamps = false;
}

【问题讨论】:

  • 你在查询中有这个:where("user_id", $user_id); 它使用 user_id = $user_id 过滤详细信息
  • 是的,先生。实际上,我用它来确保我只得到我的线程。除此之外,我想检索我的线程中存在的所有用户。但是,它只返回我在线程中的记录。如果您需要更多信息,请告诉我。
  • 恕我直言,您正在过滤 Detail 模型而不是 Thread 模型。另外据我所知,ThreadDetailsModel 的 primaryKey 应该是thread_detail_id。您可以调试您的查询,只需添加->toSql()
  • 感谢您指出这一点。我已经更新了这个问题。我错误地在发布问题时在这里写错了主要内容。这在我的代码中是正确的,并且订阅的用户出现在详细信息表中。这就是为什么我也在检查是否只选择我的线程。你能建议应该怎么做才能从我的线程中挑选所有用户吗?
  • 请定义您何时谈论your Thread。线程模型没有任何user_id,因此不属于任何人

标签: mysql laravel laravel-5.7 laravel-5.8


【解决方案1】:

tblthread 应该与用户相关联。因此,您可以在其上定义user_id 列。

查询应如下所示:

ThreadModel::where('user_id', $user_id)->with("Details")->get();
// So first you get all the threads that belong to you
// and then get all details for those threads (only)

希望对你有帮助!

【讨论】:

  • 这行不通,因为tblthread 表中没有user_id。
  • 这就是我建议首先在tblthread 模型上创建user_id。线程必须与创建它的用户相关联。这很有意义。
  • 我明白了,你的建议是对的,但这并不能解决 OP 问题:/
  • 我认为确实如此。我正试图指导他找到适当的解决方案。正如他在 cmets 中提到的那样,他可以更改表的架构。
  • 哦,我错过了那部分。在这种情况下,您应该在解决方案中包含所有这些细节,以便引导 OP 走上正确的道路。
【解决方案2】:

问题出在这里:

ThreadModel::with(["Details" => function($query) use ($user_id) {
    $query->where("user_id", $user_id);
}])->get();

此查询将过滤所有仅包含user_id = $user_id 的相关details。因此,当然,只会返回与 $user_id 相关的详细信息。所以,基本上你是在限制相关模型..而不是线程本身。因此,可能会返回一些没有与用户 $user_id 关联的任何详细信息的线程,我认为您不希望...

试试这个:

  • 检查Thread 是否至少有一个关联的Detail 属于user_id = $user_id。
  • 加载所有Details 的Threads。

所以这应该有效:

use Illuminate\Database\Eloquent\Builder;

// ...

public function myCoolMethod()
{
    $threads = ThreadModel
        ::has('details', function (Builder $query) use ($user_id) {
            $query->where('user_id', $user_id);
        })
        ->with('details')
        ->get();

    // ...
}

- 使用has() 方法,我们正在检查relationship existence。 - 使用with() 方法,我们是eager loading 被选中的threads 的所有相关细节。

【讨论】:

    【解决方案3】:

    whereHas解决了我的问题

    ThreadModel
        ::whereHas('details', function (Builder $query) use ($user_id) {
            $query->where('user_id', $user_id);
        })
        ->with('details')
        ->get();
    

    【讨论】:

      猜你喜欢
      • 2012-08-05
      • 2013-02-02
      • 2014-03-13
      • 1970-01-01
      • 2022-10-21
      • 1970-01-01
      • 2019-03-07
      • 1970-01-01
      • 2022-07-01
      相关资源
      最近更新 更多