Laravel hasMany 是返回无结果

Posted

技术标签:

【中文标题】Laravel hasMany 是返回无结果【英文标题】:Laravel hasMany is Return No Results 【发布时间】:2021-08-08 15:34:24 【问题描述】:

在 Laravel 中,我正在创建消息线程功能。我的架构如下所示:

MessageThreads 表

column
id

MessageThreadParticapants 表

column
thread_id
user_id

而我有MessageThreadMessageThreadParticapant的对应模型。在 MessageThread 模型中,我有以下关系:

public function users() 
        return $this->hasMany(MessageThreadParticapant::class, 'thread_id', 'id');

这就是事情变得有趣的地方。如果我这样做:

MessageThread->users

我得到一个空的结果。但如果我这样做:

MessageThreadParticapant::where('thread_id', $same_thread_id)->get()

我得到了正确数量的结果。我在这里做错了什么?

更新

其中一个建议是“hasMany(Model, 'foreign_key', 'local_key')”不正确。更多的上下文,它没有通过我的单元测试。我正在测试这样的测试:

public function testUsers() 

        $thread1 = MessageThread::factory()->create();

        $thread2 = MessageThread::factory()->create();

        $this->assertCount(0, $thread1->users);

        $this->assertCount(0, $thread2->users);

        $user1 = User::factory()->create();

        $user2 = User::factory()->create();

        $user3 = User::factory()->create();

        $user4 = User::factory()->create();

        MessageThreadParticapant::factory()->create([
            'user_id' => $user1->id,
            'thread_id' => $thread1->id
        ]);

        MessageThreadParticapant::factory()->create([
            'user_id' => $user2->id,
            'thread_id' => $thread1->id
        ]);

        MessageThreadParticapant::factory()->create([
            'user_id' => $user2->id,
            'thread_id' => $thread2->id
        ]);

        MessageThreadParticapant::factory()->create([
            'user_id' => $user3->id,
            'thread_id' => $thread2->id
        ]);

        MessageThreadParticapant::factory()->create([
            'user_id' => $user4->id,
            'thread_id' => $thread2->id
        ]);

        //PASSES!!!!
        $this->assertCount(2, MessageThreadParticapant::where('thread_id', $thread1->id)->get());
        //FAILS!!!
        $this->assertCount(2, $thread1->users);

        $this->assertCount(3, $thread2->users);
    

在我的测试底部:

  //PASSES!!!!
        $this->assertCount(2, MessageThreadParticapant::where('thread_id', $thread1->id)->get());
        //FAILS!!!
        $this->assertCount(2, $thread1->users);

在其他测试中,$thread->users 可以正常工作以获取正确数量的用户。为什么这些会得到不同的结果?

【问题讨论】:

@sta 我更新了上面的回复。它可以在测试之外的生产环境中工作,但只会在测试中失败。 检查你的表引擎,好像你的测试服务器数据库引擎是 InnoDB 而你的生产表引擎是 MyISAM 你逆向工作吗?例如 messageThreads 模型中的 User 关系。 【参考方案1】:

我分两步解决了这个问题。

    刷新

延迟加载显然只代表对象在加载时的状态。这意味着当调用连接属性时,它不会从数据库中检索新数据。要解决此问题,只需刷新模型,然后访问连接的属性。

$model->refresh();
$model->users;
    字符串 ID

我在 Postegresql 中使用 UUID。即使是我在模型中使用$cast = ['id' => 'string']; 的那些,这还不够。我还要补充:

protected $keyType =  'string';

【讨论】:

以上是关于Laravel hasMany 是返回无结果的主要内容,如果未能解决你的问题,请参考以下文章

Laravel HasMany 查询最新入口并返回相关模型

是否可以从 Laravel 中的 hasmany 关系中返回特定的索引元素?

Laravel hasMany 到复合表返回空数组

我的模型Laravel如何能够在hasMany中返回每个项目的所有价格?

如果 id 不为 null 则返回,laravel 雄辩

Laravel同步hasMany与belongsTo数组